From 91a87b8b490fc2daaf7d92880ce4ad8085ed85ff Mon Sep 17 00:00:00 2001 From: kyle1james Date: Thu, 7 May 2020 16:29:47 -0400 Subject: [PATCH 1/9] eslint and prettier --- .eslintrc | 68 +--- .prettierignore | 4 + .prettierrc | 3 + Gruntfile.js | 9 +- package-lock.json | 50 +++ package.json | 6 +- src/amplitude.js | 61 ++-- src/app.js | 2 - src/audioVoice.js | 37 +- src/audioWorklet/amplitudeProcessor.js | 30 +- src/audioWorklet/index.js | 20 +- src/audioWorklet/processorNames.js | 2 +- src/audioWorklet/recorderProcessor.js | 18 +- src/audioWorklet/ringBuffer.js | 2 +- src/audiocontext.js | 17 +- src/audioin.js | 78 +++-- src/compressor.js | 200 ++++++----- src/delay.js | 47 ++- src/distortion.js | 30 +- src/effect.js | 44 +-- src/envelope.js | 165 +++++---- src/eq.js | 59 ++-- src/eqFilter.js | 13 +- src/errorHandler.js | 4 +- src/fft.js | 62 ++-- src/filter.js | 157 +++++---- src/gain.js | 14 +- src/helpers.js | 65 ++-- src/listener3d.js | 311 +++++++++-------- src/looper.js | 68 ++-- src/master.js | 16 +- src/metro.js | 40 +-- src/monosynth.js | 426 ++++++++++++----------- src/noise.js | 53 +-- src/onsetDetect.js | 14 +- src/oscillator.js | 97 +++--- src/panner.js | 31 +- src/panner3d.js | 158 +++++---- src/peakDetect.js | 17 +- src/polysynth.js | 208 ++++++------ src/pulse.js | 48 +-- src/reverb.js | 136 +++++--- src/shims.js | 135 ++++---- src/signal.js | 49 ++- src/soundLoop.js | 89 ++--- src/soundRecorder.js | 43 +-- src/soundfile.js | 451 ++++++++++++++----------- test/tests/p5.Amplitude.js | 38 +-- test/tests/p5.AudioIn.js | 20 +- test/tests/p5.AudioVoice.js | 8 +- test/tests/p5.Compressor.js | 12 +- test/tests/p5.Delay.js | 15 +- test/tests/p5.Distortion.js | 8 +- test/tests/p5.EQ.js | 20 +- test/tests/p5.Effect.js | 14 +- test/tests/p5.FFT.js | 22 +- test/tests/p5.Filter.js | 14 +- test/tests/p5.MonoSynth.js | 13 +- test/tests/p5.Oscillator.js | 28 +- test/tests/p5.PolySynth.js | 16 +- test/tests/p5.Reverb.js | 17 +- test/tests/p5.SoundFile.js | 73 ++-- test/tests/p5.SoundRecorder.js | 59 ++-- 63 files changed, 2190 insertions(+), 1844 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.eslintrc b/.eslintrc index a9e015bd..84023bf6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,67 +13,23 @@ "Float32Array": true, "Uint8Array": true }, + "extends": ["eslint:recommended", "prettier"], + "plugins": ["prettier"], "rules": { - "block-scoped-var": 0, - "camelcase": 0, - "comma-style": [ - 2, - "last" - ], - "dot-notation": [ + "prettier/prettier": ["error"], + "no-cond-assign": [2, "except-parens"], + "eqeqeq": ["error", "smart"], + "no-use-before-define": [ 2, { - "allowKeywords": true + "functions": false } ], - "eqeqeq": [ - 2, - "allow-null" - ], - "eol-last": ["error", "always"], - "guard-for-in": 2, - "indent": ["error", 2, { "SwitchCase": 1 }], - "max-len": [1, 120, 2, { "ignoreComments": true }], - "new-cap": 2, + "new-cap": 0, "no-caller": 2, - "no-cond-assign": [ - 2, - "except-parens" - ], - "no-debugger": 2, - "no-empty": 2, - "no-eval": 2, - "no-extend-native": 2, - "no-extra-parens": 2, - "no-extra-semi": 2, - "no-irregular-whitespace": 2, - "no-trailing-spaces": 2, - "no-iterator": 2, - "no-loop-func": 0, - "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1 }], - "no-multi-str": 2, - "no-new": 2, - "no-plusplus": 0, - "no-proto": 2, - "no-script-url": 2, - "no-sequences": 2, - "no-shadow": 2, - "no-undef": 2, - "no-unused-vars": 2, - "no-with": 2, - "quotes": [ - 2, - "single" - ], - "semi": [ - 2 - ], - "space-before-blocks": "error", - "strict": 2, - "valid-typeof": 2, - "wrap-iife": [ - 2, - "inside" - ] + "no-undef": 0, + "no-unused-vars": ["error", { "args": "none" }], + "no-empty": ["error", { "allowEmptyCatch": true }], + "no-console": "off" } } diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..f1c00568 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +Gruntfile.js +test/test.js +webpack.config.js +lib/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..544138be --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/Gruntfile.js b/Gruntfile.js index 8960267f..b47c92ab 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -23,7 +23,10 @@ module.exports = function(grunt) { // Configure style consistency eslint: { source: { - options: {configFile: './.eslintrc'}, + options: { + configFile: './.eslintrc', + fix: true + }, src: ['src/**/*.js', 'test/tests/**/*.js'] } }, @@ -56,7 +59,7 @@ module.exports = function(grunt) { } }); - + grunt.loadNpmTasks('grunt-webpack'); grunt.loadNpmTasks('grunt-eslint'); grunt.loadNpmTasks('grunt-contrib-connect'); @@ -65,7 +68,7 @@ module.exports = function(grunt) { grunt.registerTask('lint', ['eslint:source']); grunt.registerTask('default', ['webpack:prod', 'decomment']); - grunt.registerTask('dev', ['connect','webpack:dev', 'decomment']); + grunt.registerTask('dev', ['eslint','connect','webpack:dev', 'decomment']); grunt.registerTask('serve', 'connect:server:keepalive'); grunt.registerTask('run-tests', ['serve', 'open']); }; diff --git a/package-lock.json b/package-lock.json index b5a1f5f1..b3ed22db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2888,6 +2888,24 @@ } } }, + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz", + "integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "eslint-scope": { "version": "3.7.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", @@ -3220,6 +3238,12 @@ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -4073,6 +4097,12 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -6019,6 +6049,21 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -7344,6 +7389,11 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==" + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", diff --git a/package.json b/package.json index ed1554ac..f4f09928 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "amdclean": "~2.0", "babel-loader": "^8.0.6", "babel-plugin-preval": "^3.0.1", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-prettier": "^3.1.3", "grunt": "~0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-connect": "^1.0.2", @@ -21,6 +23,7 @@ "grunt-mocha": "^1.0.4", "grunt-open": "^0.2.3", "grunt-webpack": "^3.1.3", + "prettier": "2.0.5", "raw-loader": "^3.0.0", "uglify-loader": "^3.0.0", "uglifyjs-webpack-plugin": "^2.1.3", @@ -30,7 +33,8 @@ "dependencies": { "audioworklet-polyfill": "^1.1.2", "startaudiocontext": "^1.2.1", - "tone": "0.10.0" + "tone": "0.10.0", + "tslint-config-prettier": "^1.18.0" }, "scripts": { "build": "grunt", diff --git a/src/amplitude.js b/src/amplitude.js index 051bbed4..06332b64 100644 --- a/src/amplitude.js +++ b/src/amplitude.js @@ -47,26 +47,29 @@ define(function (require) { * * */ - p5.Amplitude = function(smoothing) { - + p5.Amplitude = function (smoothing) { // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default this.bufferSize = safeBufferSize(2048); // set audio context this.audiocontext = p5sound.audiocontext; - this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, { - outputChannelCount: [1], + this._workletNode = new AudioWorkletNode( + this.audiocontext, + processorNames.amplitudeProcessor, + { + outputChannelCount: [1], - parameterData: { smoothing: smoothing || 0 }, - processorOptions: { - normalize: false, - smoothing: smoothing || 0, - numInputChannels: 2, - bufferSize: this.bufferSize + parameterData: { smoothing: smoothing || 0 }, + processorOptions: { + normalize: false, + smoothing: smoothing || 0, + numInputChannels: 2, + bufferSize: this.bufferSize, + }, } - }); + ); - this._workletNode.port.onmessage = function(event) { + this._workletNode.port.onmessage = function (event) { if (event.data.name === 'amplitude') { this.volume = event.data.volume; this.volNorm = event.data.volNorm; @@ -146,8 +149,7 @@ define(function (require) { * } * */ - p5.Amplitude.prototype.setInput = function(source, smoothing) { - + p5.Amplitude.prototype.setInput = function (source, smoothing) { p5sound.meter.disconnect(); if (smoothing) { @@ -156,7 +158,9 @@ define(function (require) { // connect to the master out of p5s instance if no snd is provided if (source == null) { - console.log('Amplitude input source is not ready! Connecting to master output instead'); + console.log( + 'Amplitude input source is not ready! Connecting to master output instead' + ); p5sound.meter.connect(this._workletNode); } @@ -177,7 +181,7 @@ define(function (require) { } }; - p5.Amplitude.prototype.connect = function(unit) { + p5.Amplitude.prototype.connect = function (unit) { if (unit) { if (unit.hasOwnProperty('input')) { this.output.connect(unit.input); @@ -189,7 +193,7 @@ define(function (require) { } }; - p5.Amplitude.prototype.disconnect = function() { + p5.Amplitude.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } @@ -234,18 +238,16 @@ define(function (require) { * } * */ - p5.Amplitude.prototype.getLevel = function(channel) { + p5.Amplitude.prototype.getLevel = function (channel) { if (typeof channel !== 'undefined') { if (this.normalize) { return this.stereoVolNorm[channel]; } else { return this.stereoVol[channel]; } - } - else if (this.normalize) { + } else if (this.normalize) { return this.volNorm; - } - else { + } else { return this.volume; } }; @@ -264,14 +266,16 @@ define(function (require) { * @for p5.Amplitude * @param {boolean} [boolean] set normalize to true (1) or false (0) */ - p5.Amplitude.prototype.toggleNormalize = function(bool) { + p5.Amplitude.prototype.toggleNormalize = function (bool) { if (typeof bool === 'boolean') { this.normalize = bool; - } - else { + } else { this.normalize = !this.normalize; } - this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize }); + this._workletNode.port.postMessage({ + name: 'toggleNormalize', + normalize: this.normalize, + }); }; /** @@ -282,7 +286,7 @@ define(function (require) { * @for p5.Amplitude * @param {Number} set smoothing from 0.0 <= 1 */ - p5.Amplitude.prototype.smooth = function(s) { + p5.Amplitude.prototype.smooth = function (s) { if (s >= 0 && s < 1) { this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s }); } else { @@ -290,7 +294,7 @@ define(function (require) { } }; - p5.Amplitude.prototype.dispose = function() { + p5.Amplitude.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -307,5 +311,4 @@ define(function (require) { this._workletNode.disconnect(); delete this._workletNode; }; - }); diff --git a/src/app.js b/src/app.js index b0ba28e7..7881c1b2 100644 --- a/src/app.js +++ b/src/app.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - require('audioworklet-polyfill'); require('shims'); require('audiocontext'); @@ -40,5 +39,4 @@ define(function (require) { require('polysynth'); return p5SOUND; - }); diff --git a/src/audioVoice.js b/src/audioVoice.js index 91bd21b4..7678ad56 100644 --- a/src/audioVoice.js +++ b/src/audioVoice.js @@ -1,5 +1,5 @@ 'use strict'; -define(function() { +define(function () { var p5sound = require('master'); /** @@ -11,23 +11,28 @@ define(function() { * @constructor */ p5.AudioVoice = function () { - this.ac = p5sound.audiocontext; - this.output = this.ac.createGain(); - this.connect(); - p5sound.soundArray.push(this); + this.ac = p5sound.audiocontext; + this.output = this.ac.createGain(); + this.connect(); + p5sound.soundArray.push(this); }; - p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) { - }; + p5.AudioVoice.prototype.play = function ( + note, + velocity, + secondsFromNow, + sustime + ) {}; - p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) { - }; + p5.AudioVoice.prototype.triggerAttack = function ( + note, + velocity, + secondsFromNow + ) {}; - p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) { - }; + p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {}; - p5.AudioVoice.prototype.amp = function(vol, rampTime) { - }; + p5.AudioVoice.prototype.amp = function (vol, rampTime) {}; /** * Connect to p5 objects or Web Audio Nodes @@ -35,7 +40,7 @@ define(function() { * @for p5.AudioVoice * @param {Object} unit */ - p5.AudioVoice.prototype.connect = function(unit) { + p5.AudioVoice.prototype.connect = function (unit) { var u = unit || p5sound.input; this.output.connect(u.input ? u.input : u); }; @@ -45,11 +50,11 @@ define(function() { * @method disconnect * @for p5.AudioVoice */ - p5.AudioVoice.prototype.disconnect = function() { + p5.AudioVoice.prototype.disconnect = function () { this.output.disconnect(); }; - p5.AudioVoice.prototype.dispose = function() { + p5.AudioVoice.prototype.dispose = function () { if (this.output) { this.output.disconnect(); delete this.output; diff --git a/src/audioWorklet/amplitudeProcessor.js b/src/audioWorklet/amplitudeProcessor.js index e7384e2f..cb2359f0 100644 --- a/src/audioWorklet/amplitudeProcessor.js +++ b/src/audioWorklet/amplitudeProcessor.js @@ -13,9 +13,17 @@ class AmplitudeProcessor extends AudioWorkletProcessor { this.smoothing = processorOptions.smoothing || 0; this.bufferSize = processorOptions.bufferSize || 2048; - this.inputRingBuffer = new RingBuffer(this.bufferSize, this.numInputChannels); - this.outputRingBuffer = new RingBuffer(this.bufferSize, this.numOutputChannels); - this.inputRingBufferArraySequence = new Array(this.numInputChannels).fill(null).map(() => new Float32Array(this.bufferSize)); + this.inputRingBuffer = new RingBuffer( + this.bufferSize, + this.numInputChannels + ); + this.outputRingBuffer = new RingBuffer( + this.bufferSize, + this.numOutputChannels + ); + this.inputRingBufferArraySequence = new Array(this.numInputChannels) + .fill(null) + .map(() => new Float32Array(this.bufferSize)); this.stereoVol = [0, 0]; this.stereoVolNorm = [0, 0]; @@ -51,7 +59,9 @@ class AmplitudeProcessor extends AudioWorkletProcessor { for (var i = 0; i < bufLength; i++) { const x = inputBuffer[i]; if (this.normalize) { - sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1); + sum += + Math.max(Math.min(x / this.volMax, 1), -1) * + Math.max(Math.min(x / this.volMax, 1), -1); } else { sum += x * x; } @@ -60,14 +70,20 @@ class AmplitudeProcessor extends AudioWorkletProcessor { // ... then take the square root of the sum. const rms = Math.sqrt(sum / bufLength); - this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing); + this.stereoVol[channel] = Math.max( + rms, + this.stereoVol[channel] * smoothing + ); this.volMax = Math.max(this.stereoVol[channel], this.volMax); } // calculate stero normalized volume and add volume from all channels together let volSum = 0; for (let index = 0; index < this.stereoVol.length; index++) { - this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0); + this.stereoVolNorm[index] = Math.max( + Math.min(this.stereoVol[index] / this.volMax, 1), + 0 + ); volSum += this.stereoVol[index]; } @@ -82,7 +98,7 @@ class AmplitudeProcessor extends AudioWorkletProcessor { volume: volume, volNorm: volNorm, stereoVol: this.stereoVol, - stereoVolNorm: this.stereoVolNorm + stereoVolNorm: this.stereoVolNorm, }); // pass input through to output diff --git a/src/audioWorklet/index.js b/src/audioWorklet/index.js index 18e4a05a..9e87f2d2 100644 --- a/src/audioWorklet/index.js +++ b/src/audioWorklet/index.js @@ -2,30 +2,32 @@ const p5sound = require('master'); const moduleSources = [ require('raw-loader!./recorderProcessor').default, require('raw-loader!./soundFileProcessor').default, - require('raw-loader!./amplitudeProcessor').default + require('raw-loader!./amplitudeProcessor').default, ]; const ac = p5sound.audiocontext; let initializedAudioWorklets = false; function loadAudioWorkletModules() { - return Promise.all(moduleSources.map(function(moduleSrc) { - const blob = new Blob([moduleSrc], { type: 'application/javascript' }); - const objectURL = URL.createObjectURL(blob); - return ac.audioWorklet.addModule(objectURL); - })); + return Promise.all( + moduleSources.map(function (moduleSrc) { + const blob = new Blob([moduleSrc], { type: 'application/javascript' }); + const objectURL = URL.createObjectURL(blob); + return ac.audioWorklet.addModule(objectURL); + }) + ); } -p5.prototype.registerMethod('init', function() { +p5.prototype.registerMethod('init', function () { if (initializedAudioWorklets) return; // ensure that a preload function exists so that p5 will wait for preloads to finish if (!this.preload && !window.preload) { - this.preload = function() {}; + this.preload = function () {}; } // use p5's preload system to load necessary AudioWorklet modules before setup() this._incrementPreload(); - const onWorkletModulesLoad = function() { + const onWorkletModulesLoad = function () { initializedAudioWorklets = true; this._decrementPreload(); }.bind(this); diff --git a/src/audioWorklet/processorNames.js b/src/audioWorklet/processorNames.js index c8402b89..d9a1fbe7 100644 --- a/src/audioWorklet/processorNames.js +++ b/src/audioWorklet/processorNames.js @@ -1,5 +1,5 @@ module.exports = { recorderProcessor: 'recorder-processor', soundFileProcessor: 'sound-file-processor', - amplitudeProcessor: 'amplitude-processor' + amplitudeProcessor: 'amplitude-processor', }; diff --git a/src/audioWorklet/recorderProcessor.js b/src/audioWorklet/recorderProcessor.js index 47417cbc..a4ba5516 100644 --- a/src/audioWorklet/recorderProcessor.js +++ b/src/audioWorklet/recorderProcessor.js @@ -40,7 +40,9 @@ class RecorderProcessor extends AudioWorkletProcessor { this.inputRingBuffer.pull(this.inputRingBufferArraySequence); for (let channel = 0; channel < this.numOutputChannels; ++channel) { - const inputChannelCopy = this.inputRingBufferArraySequence[channel].slice(); + const inputChannelCopy = this.inputRingBufferArraySequence[ + channel + ].slice(); if (channel === 0) { this.leftBuffers.push(inputChannelCopy); if (this.numInputChannels === 1) { @@ -68,7 +70,10 @@ class RecorderProcessor extends AudioWorkletProcessor { const buffers = this.getBuffers(); const leftBuffer = buffers[0].buffer; const rightBuffer = buffers[1].buffer; - this.port.postMessage({ name: 'buffers', leftBuffer: leftBuffer, rightBuffer: rightBuffer }, [leftBuffer, rightBuffer]); + this.port.postMessage( + { name: 'buffers', leftBuffer: leftBuffer, rightBuffer: rightBuffer }, + [leftBuffer, rightBuffer] + ); this.clear(); } @@ -94,8 +99,13 @@ class RecorderProcessor extends AudioWorkletProcessor { clear() { this.leftBuffers = []; this.rightBuffers = []; - this.inputRingBuffer = new RingBuffer(this.bufferSize, this.numInputChannels); - this.inputRingBufferArraySequence = new Array(this.numInputChannels).fill(null).map(() => new Float32Array(this.bufferSize)); + this.inputRingBuffer = new RingBuffer( + this.bufferSize, + this.numInputChannels + ); + this.inputRingBufferArraySequence = new Array(this.numInputChannels) + .fill(null) + .map(() => new Float32Array(this.bufferSize)); this.recordedSamples = 0; this.sampleLimit = null; } diff --git a/src/audioWorklet/ringBuffer.js b/src/audioWorklet/ringBuffer.js index 8f19bdb3..80dc06e9 100644 --- a/src/audioWorklet/ringBuffer.js +++ b/src/audioWorklet/ringBuffer.js @@ -121,5 +121,5 @@ class RingBuffer { // export an object for compatibility with preval.require() module.exports = { - default: RingBuffer + default: RingBuffer, }; diff --git a/src/audiocontext.js b/src/audiocontext.js index 7f0ef7e2..6a34aee3 100644 --- a/src/audiocontext.js +++ b/src/audiocontext.js @@ -2,7 +2,11 @@ global.TONE_SILENCE_VERSION_LOGGING = true; -define(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) { +define(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function ( + StartAudioContext, + Context, + Tone +) { // Create the Audio Context const audiocontext = new window.AudioContext(); @@ -45,11 +49,10 @@ define(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (S * * */ - p5.prototype.getAudioContext = function() { + p5.prototype.getAudioContext = function () { return audiocontext; }; - /** *

It is not only a good practice to give users control over starting * audio. This policy is enforced by many web browsers, including iOS and @@ -103,12 +106,14 @@ define(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (S * } * */ - p5.prototype.userStartAudio = function(elements, callback) { + p5.prototype.userStartAudio = function (elements, callback) { var elt = elements; if (elements instanceof p5.Element) { elt = elements.elt; - } else if (elements instanceof Array && elements[0] instanceof p5.Element ) { - elt = elements.map(function(e) { return e.elt}); + } else if (elements instanceof Array && elements[0] instanceof p5.Element) { + elt = elements.map(function (e) { + return e.elt; + }); } return StartAudioContext(audiocontext, elt, callback); }; diff --git a/src/audioin.js b/src/audioin.js index 567bc4ab..cc012058 100644 --- a/src/audioin.js +++ b/src/audioin.js @@ -50,7 +50,7 @@ define(function (require) { * } * */ - p5.AudioIn = function(errorCallback) { + p5.AudioIn = function (errorCallback) { // set up audio input /** * @property {GainNode} input @@ -90,8 +90,16 @@ define(function (require) { this.amplitude = new p5.Amplitude(); this.output.connect(this.amplitude.input); - if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) { - errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices'); + if ( + !window.MediaStreamTrack || + !window.navigator.mediaDevices || + !window.navigator.mediaDevices.getUserMedia + ) { + errorCallback + ? errorCallback() + : window.alert( + 'This browser does not support MediaStreamTrack and mediaDevices' + ); } // add to soundArray so we can dispose on close @@ -118,7 +126,7 @@ define(function (require) { * some browsers do not support * getUserMedia. */ - p5.AudioIn.prototype.start = function(successCallback, errorCallback) { + p5.AudioIn.prototype.start = function (successCallback, errorCallback) { var self = this; if (this.stream) { @@ -130,8 +138,8 @@ define(function (require) { var constraints = { audio: { sampleRate: p5sound.audiocontext.sampleRate, - echoCancellation: false - } + echoCancellation: false, + }, }; // if developers determine which source to use @@ -139,8 +147,9 @@ define(function (require) { constraints.audio.deviceId = audioSource.deviceId; } - window.navigator.mediaDevices.getUserMedia( constraints ) - .then( function(stream) { + window.navigator.mediaDevices + .getUserMedia(constraints) + .then(function (stream) { self.stream = stream; self.enabled = true; // Wrap a MediaStreamSourceNode around the live input @@ -150,7 +159,7 @@ define(function (require) { self.amplitude.setInput(self.output); if (successCallback) successCallback(); }) - .catch( function(err) { + .catch(function (err) { if (errorCallback) errorCallback(err); else console.error(err); }); @@ -163,9 +172,9 @@ define(function (require) { * @method stop * @for p5.AudioIn */ - p5.AudioIn.prototype.stop = function() { + p5.AudioIn.prototype.stop = function () { if (this.stream) { - this.stream.getTracks().forEach(function(track) { + this.stream.getTracks().forEach(function (track) { track.stop(); }); @@ -185,19 +194,16 @@ define(function (require) { * @param {Object} [unit] An object that accepts audio input, * such as an FFT */ - p5.AudioIn.prototype.connect = function(unit) { + p5.AudioIn.prototype.connect = function (unit) { if (unit) { if (unit.hasOwnProperty('input')) { this.output.connect(unit.input); - } - else if (unit.hasOwnProperty('analyser')) { + } else if (unit.hasOwnProperty('analyser')) { this.output.connect(unit.analyser); - } - else { + } else { this.output.connect(unit); } - } - else { + } else { this.output.connect(p5sound.input); } }; @@ -210,7 +216,7 @@ define(function (require) { * @method disconnect * @for p5.AudioIn */ - p5.AudioIn.prototype.disconnect = function() { + p5.AudioIn.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); // stay connected to amplitude even if not outputting to p5 @@ -231,7 +237,7 @@ define(function (require) { * Smooths values based on previous values. * @return {Number} Volume level (between 0.0 and 1.0) */ - p5.AudioIn.prototype.getLevel = function(smoothing) { + p5.AudioIn.prototype.getLevel = function (smoothing) { if (smoothing) { this.amplitude.smoothing = smoothing; } @@ -246,13 +252,19 @@ define(function (require) { * @param {Number} vol between 0 and 1.0 * @param {Number} [time] ramp time (optional) */ - p5.AudioIn.prototype.amp = function(vol, t) { + p5.AudioIn.prototype.amp = function (vol, t) { if (t) { var rampTime = t || 0; var currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime); - this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime); - this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime); + this.output.gain.setValueAtTime( + currentVol, + p5sound.audiocontext.currentTime + ); + this.output.gain.linearRampToValueAtTime( + vol, + rampTime + p5sound.audiocontext.currentTime + ); } else { this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime); this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime); @@ -295,10 +307,11 @@ define(function (require) { * */ p5.AudioIn.prototype.getSources = function (onSuccess, onError) { - return new Promise( function(resolve, reject) { - window.navigator.mediaDevices.enumerateDevices() - .then( function(devices) { - p5sound.inputSources = devices.filter(function(device) { + return new Promise(function (resolve, reject) { + window.navigator.mediaDevices + .enumerateDevices() + .then(function (devices) { + p5sound.inputSources = devices.filter(function (device) { return device.kind === 'audioinput'; }); resolve(p5sound.inputSources); @@ -306,12 +319,14 @@ define(function (require) { onSuccess(p5sound.inputSources); } }) - .catch( function(error) { + .catch(function (error) { reject(error); if (onError) { onError(error); } else { - console.error('This browser does not support MediaStreamTrack.getSources()'); + console.error( + 'This browser does not support MediaStreamTrack.getSources()' + ); } }); }); @@ -348,7 +363,7 @@ define(function (require) { * } * */ - p5.AudioIn.prototype.setSource = function(num) { + p5.AudioIn.prototype.setSource = function (num) { if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) { // set the current source this.currentSource = num; @@ -364,7 +379,7 @@ define(function (require) { }; // private method - p5.AudioIn.prototype.dispose = function() { + p5.AudioIn.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -380,5 +395,4 @@ define(function (require) { delete this.amplitude; delete this.output; }; - }); diff --git a/src/compressor.js b/src/compressor.js index f075050c..589920b3 100644 --- a/src/compressor.js +++ b/src/compressor.js @@ -1,8 +1,8 @@ define(function (require) { - 'use strict'; + 'use strict'; - var p5sound = require('master'); - var Effect = require('effect'); + var p5sound = require('master'); + var Effect = require('effect'); var CustomError = require('errorHandler'); /** @@ -26,50 +26,55 @@ define(function (require) { * * */ - p5.Compressor = function() { - Effect.call(this); + p5.Compressor = function () { + Effect.call(this); /** * The p5.Compressor is built with a Web Audio Dynamics Compressor Node - * + * target="_blank" title="W3 spec for Dynamics Compressor Node">Web Audio Dynamics Compressor Node + * * @property {AudioNode} compressor */ - - this.compressor = this.ac.createDynamicsCompressor(); + this.compressor = this.ac.createDynamicsCompressor(); this.input.connect(this.compressor); this.compressor.connect(this.wet); - }; - - p5.Compressor.prototype = Object.create(Effect.prototype); - - /** - * Performs the same function as .connect, but also accepts - * optional parameters to set compressor's audioParams - * @method process - * @for p5.Compressor - * - * @param {Object} src Sound source to be connected - * - * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB, - * default = .003, range 0 - 1 - * @param {Number} [knee] A decibel value representing the range above the - * threshold where the curve smoothly transitions to the "ratio" portion. - * default = 30, range 0 - 40 - * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output - * default = 12, range 1 - 20 - * @param {Number} [threshold] The decibel value above which the compression will start taking effect - * default = -24, range -100 - 0 - * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB - * default = .25, range 0 - 1 - */ - p5.Compressor.prototype.process = function(src, attack, knee, - ratio, threshold, release) { - src.connect(this.input); - this.set(attack, knee, ratio, threshold, release); - }; + }; + + p5.Compressor.prototype = Object.create(Effect.prototype); + + /** + * Performs the same function as .connect, but also accepts + * optional parameters to set compressor's audioParams + * @method process + * @for p5.Compressor + * + * @param {Object} src Sound source to be connected + * + * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB, + * default = .003, range 0 - 1 + * @param {Number} [knee] A decibel value representing the range above the + * threshold where the curve smoothly transitions to the "ratio" portion. + * default = 30, range 0 - 40 + * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output + * default = 12, range 1 - 20 + * @param {Number} [threshold] The decibel value above which the compression will start taking effect + * default = -24, range -100 - 0 + * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB + * default = .25, range 0 - 1 + */ + p5.Compressor.prototype.process = function ( + src, + attack, + knee, + ratio, + threshold, + release + ) { + src.connect(this.input); + this.set(attack, knee, ratio, threshold, release); + }; /** * Set the paramters of a compressor. @@ -87,17 +92,30 @@ define(function (require) { * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB * default = .25, range 0 - 1 */ - p5.Compressor.prototype.set = function (attack, knee, - ratio, threshold, release) { - - if (typeof attack !== 'undefined') {this.attack(attack);} - if (typeof knee !== 'undefined') {this.knee(knee);} - if (typeof ratio !== 'undefined') {this.ratio(ratio);} - if (typeof threshold !== 'undefined') {this.threshold(threshold);} - if (typeof release !== 'undefined') {this.release(release);} + p5.Compressor.prototype.set = function ( + attack, + knee, + ratio, + threshold, + release + ) { + if (typeof attack !== 'undefined') { + this.attack(attack); + } + if (typeof knee !== 'undefined') { + this.knee(knee); + } + if (typeof ratio !== 'undefined') { + this.ratio(ratio); + } + if (typeof threshold !== 'undefined') { + this.threshold(threshold); + } + if (typeof release !== 'undefined') { + this.release(release); + } }; - /** * Get current attack or set value w/ time ramp * @@ -108,20 +126,24 @@ define(function (require) { * default = .003, range 0 - 1 * @param {Number} [time] Assign time value to schedule the change in value */ - p5.Compressor.prototype.attack = function (attack, time){ + p5.Compressor.prototype.attack = function (attack, time) { var t = time || 0; - if (typeof attack == 'number'){ + if (typeof attack === 'number') { this.compressor.attack.value = attack; - this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t); + this.compressor.attack.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.compressor.attack.linearRampToValueAtTime( + attack, + this.ac.currentTime + 0.02 + t + ); } else if (typeof attack !== 'undefined') { - attack.connect(this.compressor.attack); + attack.connect(this.compressor.attack); } return this.compressor.attack.value; }; - - /** + /** * Get current knee or set value w/ time ramp * * @method knee @@ -131,19 +153,23 @@ define(function (require) { * default = 30, range 0 - 40 * @param {Number} [time] Assign time value to schedule the change in value */ - p5.Compressor.prototype.knee = function (knee, time){ + p5.Compressor.prototype.knee = function (knee, time) { var t = time || 0; - if (typeof knee == 'number'){ + if (typeof knee === 'number') { this.compressor.knee.value = knee; - this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t); + this.compressor.knee.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.compressor.knee.linearRampToValueAtTime( + knee, + this.ac.currentTime + 0.02 + t + ); } else if (typeof knee !== 'undefined') { - knee.connect(this.compressor.knee); + knee.connect(this.compressor.knee); } return this.compressor.knee.value; }; - /** * Get current ratio or set value w/ time ramp * @method ratio @@ -152,19 +178,23 @@ define(function (require) { * default = 12, range 1 - 20 * @param {Number} [time] Assign time value to schedule the change in value */ - p5.Compressor.prototype.ratio = function (ratio, time){ + p5.Compressor.prototype.ratio = function (ratio, time) { var t = time || 0; - if (typeof ratio == 'number'){ + if (typeof ratio === 'number') { this.compressor.ratio.value = ratio; - this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t); + this.compressor.ratio.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.compressor.ratio.linearRampToValueAtTime( + ratio, + this.ac.currentTime + 0.02 + t + ); } else if (typeof ratio !== 'undefined') { - ratio.connect(this.compressor.ratio); + ratio.connect(this.compressor.ratio); } return this.compressor.ratio.value; }; - /** * Get current threshold or set value w/ time ramp * @method threshold @@ -173,19 +203,23 @@ define(function (require) { * default = -24, range -100 - 0 * @param {Number} [time] Assign time value to schedule the change in value */ - p5.Compressor.prototype.threshold = function (threshold, time){ + p5.Compressor.prototype.threshold = function (threshold, time) { var t = time || 0; - if (typeof threshold == 'number'){ + if (typeof threshold === 'number') { this.compressor.threshold.value = threshold; - this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t); + this.compressor.threshold.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.compressor.threshold.linearRampToValueAtTime( + threshold, + this.ac.currentTime + 0.02 + t + ); } else if (typeof threshold !== 'undefined') { - threshold.connect(this.compressor.threshold); + threshold.connect(this.compressor.threshold); } return this.compressor.threshold.value; }; - /** * Get current release or set value w/ time ramp * @method release @@ -195,14 +229,19 @@ define(function (require) { * * @param {Number} [time] Assign time value to schedule the change in value */ - p5.Compressor.prototype.release = function (release, time){ + p5.Compressor.prototype.release = function (release, time) { var t = time || 0; - if (typeof release == 'number'){ + if (typeof release === 'number') { this.compressor.release.value = release; - this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t); + this.compressor.release.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.compressor.release.linearRampToValueAtTime( + release, + this.ac.currentTime + 0.02 + t + ); } else if (typeof number !== 'undefined') { - release.connect(this.compressor.release); + release.connect(this.compressor.release); } return this.compressor.release.value; }; @@ -214,18 +253,17 @@ define(function (require) { * @for p5.Compressor * @return {Number} Value of the amount of gain reduction that is applied to the signal */ - p5.Compressor.prototype.reduction =function() { + p5.Compressor.prototype.reduction = function () { return this.compressor.reduction.value; }; - - p5.Compressor.prototype.dispose = function() { + p5.Compressor.prototype.dispose = function () { Effect.prototype.dispose.apply(this); if (this.compressor) { this.compressor.disconnect(); delete this.compressor; } - }; + }; return p5.Compressor; }); diff --git a/src/delay.js b/src/delay.js index f367cc92..473b23f9 100644 --- a/src/delay.js +++ b/src/delay.js @@ -52,8 +52,8 @@ define(function (require) { * } * */ - p5.Delay = function() { - Effect.call(this); + p5.Delay = function () { + Effect.call(this); this._split = this.ac.createChannelSplitter(2); this._merge = this.ac.createChannelMerger(2); @@ -85,7 +85,10 @@ define(function (require) { this._rightFilter.disconnect(); this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime); - this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime); + this._rightFilter.biquad.frequency.setValueAtTime( + 1200, + this.ac.currentTime + ); this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); @@ -97,7 +100,6 @@ define(function (require) { this._rightGain.connect(this._rightFilter.input); this._merge.connect(this.wet); - this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); @@ -108,8 +110,6 @@ define(function (require) { // set initial feedback to 0.5 this.feedback(0.5); - - }; p5.Delay.prototype = Object.create(Effect.prototype); @@ -130,14 +130,18 @@ define(function (require) { * below the lowPass will be part of the * delay. */ - p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) { + p5.Delay.prototype.process = function (src, _delayTime, _feedback, _filter) { var feedback = _feedback || 0; var delayTime = _delayTime || 0; if (feedback >= 1.0) { throw new Error('Feedback value will force a positive feedback loop.'); } if (delayTime >= this._maxDelay) { - throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.'); + throw new Error( + 'Delay Time exceeds maximum delay time of ' + + this._maxDelay + + ' second.' + ); } src.connect(this.input); @@ -160,14 +164,12 @@ define(function (require) { * @for p5.Delay * @param {Number} delayTime Time (in seconds) of the delay */ - p5.Delay.prototype.delayTime = function(t) { + p5.Delay.prototype.delayTime = function (t) { // if t is an audio node... if (typeof t !== 'number') { t.connect(this.leftDelay.delayTime); t.connect(this.rightDelay.delayTime); - } - - else { + } else { this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime); this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime); this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime); @@ -190,16 +192,14 @@ define(function (require) { * @returns {Number} Feedback value * */ - p5.Delay.prototype.feedback = function(f) { + p5.Delay.prototype.feedback = function (f) { // if f is an audio node... if (f && typeof f !== 'number') { f.connect(this._leftGain.gain); f.connect(this._rightGain.gain); - } - else if (f >= 1.0) { + } else if (f >= 1.0) { throw new Error('Feedback value will force a positive feedback loop.'); - } - else if (typeof f === 'number') { + } else if (typeof f === 'number') { this._leftGain.gain.value = f; this._rightGain.gain.value = f; } @@ -222,12 +222,11 @@ define(function (require) { * High numbers (i.e. 15) will produce a resonance, * low numbers (i.e. .2) will produce a slope. */ - p5.Delay.prototype.filter = function(freq, q) { + p5.Delay.prototype.filter = function (freq, q) { this._leftFilter.set(freq, q); this._rightFilter.set(freq, q); }; - /** * Choose a preset type of delay. 'pingPong' bounces the signal * from the left to the right channel to produce a stereo effect. @@ -237,7 +236,7 @@ define(function (require) { * @for p5.Delay * @param {String|Number} type 'pingPong' (1) or 'default' (0) */ - p5.Delay.prototype.setType = function(t) { + p5.Delay.prototype.setType = function (t) { if (t === 1) { t = 'pingPong'; } @@ -246,9 +245,9 @@ define(function (require) { this._rightFilter.disconnect(); this._split.connect(this.leftDelay, 0); this._split.connect(this.rightDelay, 1); - switch(t) { + switch (t) { case 'pingPong': - this._rightFilter.setType( this._leftFilter.biquad.type ); + this._rightFilter.setType(this._leftFilter.biquad.type); this._leftFilter.output.connect(this._merge, 0, 0); this._rightFilter.output.connect(this._merge, 0, 1); this._leftFilter.output.connect(this.rightDelay); @@ -287,8 +286,7 @@ define(function (require) { * @for p5.Delay */ - p5.Delay.prototype.dispose = function() { - + p5.Delay.prototype.dispose = function () { Effect.prototype.dispose.apply(this); this._split.disconnect(); @@ -309,5 +307,4 @@ define(function (require) { this.leftDelay = undefined; this.rightDelay = undefined; }; - }); diff --git a/src/distortion.js b/src/distortion.js index c657b28c..7480fcbf 100644 --- a/src/distortion.js +++ b/src/distortion.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - var Effect = require('effect'); /* @@ -14,9 +13,9 @@ define(function (require) { var deg = Math.PI / 180; var i = 0; var x; - for ( ; i < numSamples; ++i ) { - x = i * 2 / numSamples - 1; - curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) ); + for (; i < numSamples; ++i) { + x = (i * 2) / numSamples - 1; + curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x)); } return curve; } @@ -39,16 +38,19 @@ define(function (require) { * @param {String} [oversample='none'] 'none', '2x', or '4x'. * */ - p5.Distortion = function(amount, oversample) { + p5.Distortion = function (amount, oversample) { Effect.call(this); if (typeof amount === 'undefined') { amount = 0.25; - } if (typeof amount !== 'number') { + } + if (typeof amount !== 'number') { throw new Error('amount must be a number'); - } if (typeof oversample === 'undefined') { + } + if (typeof oversample === 'undefined') { oversample = '2x'; - } if (typeof oversample !== 'string') { + } + if (typeof oversample !== 'string') { throw new Error('oversample must be a String'); } @@ -74,7 +76,6 @@ define(function (require) { p5.Distortion.prototype = Object.create(Effect.prototype); - /** * Process a sound source, optionally specify amount and oversample values. * @@ -84,7 +85,7 @@ define(function (require) { * Normal values range from 0-1. * @param {String} [oversample='none'] 'none', '2x', or '4x'. */ - p5.Distortion.prototype.process = function(src, amount, oversample) { + p5.Distortion.prototype.process = function (src, amount, oversample) { src.connect(this.input); this.set(amount, oversample); }; @@ -98,7 +99,7 @@ define(function (require) { * Normal values range from 0-1. * @param {String} [oversample='none'] 'none', '2x', or '4x'. */ - p5.Distortion.prototype.set = function(amount, oversample) { + p5.Distortion.prototype.set = function (amount, oversample) { if (amount) { var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000); this.amount = curveAmount; @@ -117,7 +118,7 @@ define(function (require) { * @return {Number} Unbounded distortion amount. * Normal values range from 0-1. */ - p5.Distortion.prototype.getAmount = function() { + p5.Distortion.prototype.getAmount = function () { return this.amount; }; @@ -128,12 +129,11 @@ define(function (require) { * @for p5.Distortion * @return {String} Oversample can either be 'none', '2x', or '4x'. */ - p5.Distortion.prototype.getOversample = function() { + p5.Distortion.prototype.getOversample = function () { return this.waveShaperNode.oversample; }; - - p5.Distortion.prototype.dispose = function() { + p5.Distortion.prototype.dispose = function () { Effect.prototype.dispose.apply(this); if (this.waveShaperNode) { this.waveShaperNode.disconnect(); diff --git a/src/effect.js b/src/effect.js index 70728176..362a114b 100644 --- a/src/effect.js +++ b/src/effect.js @@ -1,6 +1,5 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); var CrossFade = require('Tone/component/CrossFade'); @@ -27,17 +26,17 @@ define(function (require) { * to the wet signal to this gain node, so that dry and wet * signals are mixed properly. */ - p5.Effect = function() { + p5.Effect = function () { this.ac = p5sound.audiocontext; this.input = this.ac.createGain(); this.output = this.ac.createGain(); - /** - * The p5.Effect class is built - * using Tone.js CrossFade - * @private - */ + /** + * The p5.Effect class is built + * using Tone.js CrossFade + * @private + */ this._drywet = new CrossFade(1); @@ -67,14 +66,20 @@ define(function (require) { * @param {Number} [rampTime] create a fade that lasts until rampTime * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds */ - p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){ + p5.Effect.prototype.amp = function (vol, rampTime, tFromNow) { var rampTime = rampTime || 0; var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; var currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(now); - this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001); - this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001); + this.output.gain.linearRampToValueAtTime( + currentVol, + now + tFromNow + 0.001 + ); + this.output.gain.linearRampToValueAtTime( + vol, + now + tFromNow + rampTime + 0.001 + ); }; /** @@ -86,11 +91,11 @@ define(function (require) { * @for p5.Effect * @param {Object} [arguments] Chain together multiple sound objects */ - p5.Effect.prototype.chain = function(){ - if (arguments.length>0){ + p5.Effect.prototype.chain = function () { + if (arguments.length > 0) { this.connect(arguments[0]); - for(var i=1;i */ - p5.Envelope = function(t1, l1, t2, l2, t3, l3) { + p5.Envelope = function (t1, l1, t2, l2, t3, l3) { /** * Time until envelope reaches attackLevel * @property attackTime @@ -88,7 +87,6 @@ define(function (require) { this._rampLowPercentage = 0.02; - this.output = p5sound.audiocontext.createGain(); this.control = new TimelineSignal(); @@ -112,7 +110,6 @@ define(function (require) { // set to true if attack is set, then false on release this.wasTriggered = false; - // add to the soundArray so we can dispose of the env later p5sound.soundArray.push(this); }; @@ -122,7 +119,7 @@ define(function (require) { p5.Envelope.prototype._init = function () { var now = p5sound.audiocontext.currentTime; var t = now; - this.control.setTargetAtTime(0.00001, t, .001); + this.control.setTargetAtTime(0.00001, t, 0.001); //also, compute the correct time constants this._setRampAD(this.aTime, this.dTime); }; @@ -177,7 +174,7 @@ define(function (require) { * * */ - p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) { + p5.Envelope.prototype.set = function (t1, l1, t2, l2, t3, l3) { this.aTime = t1; this.aLevel = l1; this.dTime = t2 || 0; @@ -246,13 +243,16 @@ define(function (require) { * } * */ - p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) { + p5.Envelope.prototype.setADSR = function (aTime, dTime, sPercent, rTime) { this.aTime = aTime; this.dTime = dTime || 0; // lerp this.sPercent = sPercent || 0; - this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0; + this.dLevel = + typeof sPercent !== 'undefined' + ? sPercent * (this.aLevel - this.rLevel) + this.rLevel + : 0; this.rTime = rTime || 0; @@ -303,7 +303,7 @@ define(function (require) { * } * */ - p5.Envelope.prototype.setRange = function(aLevel, rLevel) { + p5.Envelope.prototype.setRange = function (aLevel, rLevel) { this.aLevel = aLevel || 1; this.rLevel = rLevel || 0; @@ -328,33 +328,37 @@ define(function (require) { // param {Number} attackTimeConstant attack time constant // param {Number} decayTimeConstant decay time constant // - p5.Envelope.prototype._setRampAD = function(t1, t2) { + p5.Envelope.prototype._setRampAD = function (t1, t2) { this._rampAttackTime = this.checkExpInput(t1); this._rampDecayTime = this.checkExpInput(t2); var TCDenominator = 1.0; /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage) - TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)); + TCDenominator = Math.log( + 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage) + ); this._rampAttackTC = t1 / this.checkExpInput(TCDenominator); TCDenominator = Math.log(1.0 / this._rampLowPercentage); this._rampDecayTC = t2 / this.checkExpInput(TCDenominator); }; // private method - p5.Envelope.prototype.setRampPercentages = function(p1, p2) { + p5.Envelope.prototype.setRampPercentages = function (p1, p2) { //set the percentages that the simple exponential ramps go to this._rampHighPercentage = this.checkExpInput(p1); this._rampLowPercentage = this.checkExpInput(p2); var TCDenominator = 1.0; //now re-compute the time constants based on those percentages /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage) - TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)); - this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator); + TCDenominator = Math.log( + 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage) + ); + this._rampAttackTC = + this._rampAttackTime / this.checkExpInput(TCDenominator); TCDenominator = Math.log(1.0 / this._rampLowPercentage); this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator); }; - /** * Assign a parameter to be controlled by this envelope. * If a p5.Sound object is given, then the p5.Envelope will control its @@ -366,8 +370,8 @@ define(function (require) { * @param {Object} [...inputs] A p5.sound object or * Web Audio Param. */ - p5.Envelope.prototype.setInput = function() { - for (var i = 0; i */ - p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) { + p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) { var tFromNow = secondsFromNow || 0; var susTime = susTime || 0; @@ -463,7 +466,6 @@ define(function (require) { this.triggerAttack(unit, tFromNow); this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime); - }; /** @@ -520,8 +522,8 @@ define(function (require) { * } * */ - p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) { - var now = p5sound.audiocontext.currentTime; + p5.Envelope.prototype.triggerAttack = function (unit, secondsFromNow) { + var now = p5sound.audiocontext.currentTime; var tFromNow = secondsFromNow || 0; var t = now + tFromNow; this.lastAttack = t; @@ -536,12 +538,12 @@ define(function (require) { // get and set value (with linear ramp) to anchor automation var valToSet = this.control.getValueAtTime(t); - if (this.isExponential === true) - { - this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t); - } - else - { + if (this.isExponential === true) { + this.control.exponentialRampToValueAtTime( + this.checkExpInput(valToSet), + t + ); + } else { this.control.linearRampToValueAtTime(valToSet, t); } @@ -552,33 +554,32 @@ define(function (require) { // attack t += this.aTime; - if (this.isExponential === true) - { - this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t); + if (this.isExponential === true) { + this.control.exponentialRampToValueAtTime( + this.checkExpInput(this.aLevel), + t + ); valToSet = this.checkExpInput(this.control.getValueAtTime(t)); this.control.cancelScheduledValues(t); this.control.exponentialRampToValueAtTime(valToSet, t); - } - else - { + } else { this.control.linearRampToValueAtTime(this.aLevel, t); valToSet = this.control.getValueAtTime(t); this.control.cancelScheduledValues(t); this.control.linearRampToValueAtTime(valToSet, t); - } // decay to decay level (if using ADSR, then decay level == sustain level) t += this.dTime; - if (this.isExponential === true) - { - this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t); + if (this.isExponential === true) { + this.control.exponentialRampToValueAtTime( + this.checkExpInput(this.dLevel), + t + ); valToSet = this.checkExpInput(this.control.getValueAtTime(t)); this.control.cancelScheduledValues(t); this.control.exponentialRampToValueAtTime(valToSet, t); - } - else - { + } else { this.control.linearRampToValueAtTime(this.dLevel, t); valToSet = this.control.getValueAtTime(t); this.control.cancelScheduledValues(t); @@ -637,8 +638,7 @@ define(function (require) { * } * */ - p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) { - + p5.Envelope.prototype.triggerRelease = function (unit, secondsFromNow) { // only trigger a release if an attack was triggered if (!this.wasTriggered) { // this currently causes a bit of trouble: @@ -651,7 +651,7 @@ define(function (require) { return; } - var now = p5sound.audiocontext.currentTime; + var now = p5sound.audiocontext.currentTime; var tFromNow = secondsFromNow || 0; var t = now + tFromNow; @@ -664,27 +664,27 @@ define(function (require) { // get and set value (with linear or exponential ramp) to anchor automation var valToSet = this.control.getValueAtTime(t); - if (this.isExponential === true) - { - this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t); - } - else - { + if (this.isExponential === true) { + this.control.exponentialRampToValueAtTime( + this.checkExpInput(valToSet), + t + ); + } else { this.control.linearRampToValueAtTime(valToSet, t); } // release t += this.rTime; - if (this.isExponential === true) - { - this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t); + if (this.isExponential === true) { + this.control.exponentialRampToValueAtTime( + this.checkExpInput(this.rLevel), + t + ); valToSet = this.checkExpInput(this.control.getValueAtTime(t)); this.control.cancelScheduledValues(t); this.control.exponentialRampToValueAtTime(valToSet, t); - } - else - { + } else { this.control.linearRampToValueAtTime(this.rLevel, t); valToSet = this.control.getValueAtTime(t); this.control.cancelScheduledValues(t); @@ -746,13 +746,13 @@ define(function (require) { * } * */ - p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) { - - var now = p5sound.audiocontext.currentTime; + p5.Envelope.prototype.ramp = function (unit, secondsFromNow, v1, v2) { + var now = p5sound.audiocontext.currentTime; var tFromNow = secondsFromNow || 0; var t = now + tFromNow; var destination1 = this.checkExpInput(v1); - var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined; + var destination2 = + typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined; // connect env to unit if not already connected if (unit) { @@ -791,19 +791,19 @@ define(function (require) { } }; - - p5.Envelope.prototype.connect = function(unit) { + p5.Envelope.prototype.connect = function (unit) { this.connection = unit; // assume we're talking about output gain // unless given a different audio param - 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 + 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 ) { unit = unit.output.gain; } @@ -817,13 +817,12 @@ define(function (require) { this.output.connect(unit); }; - p5.Envelope.prototype.disconnect = function() { + p5.Envelope.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } }; - // Signal Math /** @@ -837,7 +836,7 @@ define(function (require) { * @return {p5.Envelope} Envelope Returns this envelope * with scaled output */ - p5.Envelope.prototype.add = function(num) { + p5.Envelope.prototype.add = function (num) { var add = new Add(num); var thisChain = this.mathOps.length; var nextChain = this.output; @@ -855,7 +854,7 @@ define(function (require) { * @return {p5.Envelope} Envelope Returns this envelope * with scaled output */ - p5.Envelope.prototype.mult = function(num) { + p5.Envelope.prototype.mult = function (num) { var mult = new Mult(num); var thisChain = this.mathOps.length; var nextChain = this.output; @@ -876,16 +875,15 @@ define(function (require) { * @return {p5.Envelope} Envelope Returns this envelope * with scaled output */ - p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) { + p5.Envelope.prototype.scale = function (inMin, inMax, outMin, outMax) { var scale = new Scale(inMin, inMax, outMin, outMax); var thisChain = this.mathOps.length; var nextChain = this.output; return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale); }; - // get rid of the oscillator - p5.Envelope.prototype.dispose = function() { + p5.Envelope.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -901,11 +899,12 @@ define(function (require) { }; // Different name for backwards compatibility, replicates p5.Envelope class - p5.Env = function(t1, l1, t2, l2, t3, l3) { - console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' + - 'Please use the new p5.Envelope instead.'); + p5.Env = function (t1, l1, t2, l2, t3, l3) { + console.warn( + 'WARNING: p5.Env is now deprecated and may be removed in future versions. ' + + 'Please use the new p5.Envelope instead.' + ); p5.Envelope.call(this, t1, l1, t2, l2, t3, l3); }; p5.Env.prototype = Object.create(p5.Envelope.prototype); - }); diff --git a/src/eq.js b/src/eq.js index 3ff5bcb3..ac7e1150 100644 --- a/src/eq.js +++ b/src/eq.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - var Effect = require('effect'); var EQFilter = require('eqFilter'); @@ -83,52 +82,50 @@ define(function (require) { * } * */ - p5.EQ = function(_eqsize) { + p5.EQ = function (_eqsize) { Effect.call(this); //p5.EQ can be of size (3) or (8), defaults to 3 _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3; var factor; - _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2; + _eqsize === 3 ? (factor = Math.pow(2, 3)) : (factor = 2); /** - * The p5.EQ is built with abstracted p5.Filter objects. - * To modify any bands, use methods of the - * p5.Filter API, especially `gain` and `freq`. - * Bands are stored in an array, with indices 0 - 3, or 0 - 7 - * @property {Array} bands - * - */ + * The p5.EQ is built with abstracted p5.Filter objects. + * To modify any bands, use methods of the + * p5.Filter API, especially `gain` and `freq`. + * Bands are stored in an array, with indices 0 - 3, or 0 - 7 + * @property {Array} bands + * + */ this.bands = []; - var freq, res; for (var i = 0; i < _eqsize; i++) { if (i === _eqsize - 1) { freq = 21000; - res = .01; + res = 0.01; } else if (i === 0) { freq = 100; - res = .1; - } - else if (i===1) { + res = 0.1; + } else if (i === 1) { freq = _eqsize === 3 ? 360 * factor : 360; res = 1; - }else { - freq = this.bands[i-1].freq() * factor; + } else { + freq = this.bands[i - 1].freq() * factor; res = 1; } this.bands[i] = this._newBand(freq, res); - if (i>0) { - this.bands[i-1].connect(this.bands[i].biquad); + if (i > 0) { + this.bands[i - 1].connect(this.bands[i].biquad); } else { this.input.connect(this.bands[i].biquad); } } - this.bands[_eqsize-1].connect(this.output); + this.bands[_eqsize - 1].connect(this.output); }; p5.EQ.prototype = Object.create(Effect.prototype); @@ -165,16 +162,18 @@ define(function (require) { // * @param {Number} [freq7] Frequency value for band with index 7 // * @param {Number} [gain7] Gain value for band with index 7 // */ - p5.EQ.prototype.set = function() { + p5.EQ.prototype.set = function () { if (arguments.length === this.bands.length * 2) { - for (var i = 0; i < arguments.length; i+=2) { - this.bands[i/2].freq(arguments[i]); - this.bands[i/2].gain(arguments[i+1]); + for (var i = 0; i < arguments.length; i += 2) { + this.bands[i / 2].freq(arguments[i]); + this.bands[i / 2].gain(arguments[i + 1]); } - } - else { - 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)'); + } else { + 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)' + ); } }; @@ -189,7 +188,7 @@ define(function (require) { * @param {Number} res * @return {Object} Abstracted Filter */ - p5.EQ.prototype._newBand = function(freq, res) { + p5.EQ.prototype._newBand = function (freq, res) { return new EQFilter(freq, res); }; diff --git a/src/eqFilter.js b/src/eqFilter.js index 507686ff..3a281506 100644 --- a/src/eqFilter.js +++ b/src/eqFilter.js @@ -10,7 +10,7 @@ define(function (require) { * * @private */ - var EQFilter = function(freq, res) { + var EQFilter = function (freq, res) { Filter.call(this, 'peaking'); this.disconnect(); this.set(freq, res); @@ -19,17 +19,16 @@ define(function (require) { delete this.output; delete this._drywet; delete this.wet; - }; EQFilter.prototype = Object.create(Filter.prototype); - EQFilter.prototype.amp = function() { + EQFilter.prototype.amp = function () { console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`'); }; - EQFilter.prototype.drywet = function() { + EQFilter.prototype.drywet = function () { console.warn('`drywet()` is not available for p5.EQ bands.'); }; - EQFilter.prototype.connect = function(unit) { + EQFilter.prototype.connect = function (unit) { var u = unit || p5.soundOut.input; if (this.biquad) { this.biquad.connect(u.input ? u.input : u); @@ -38,12 +37,12 @@ define(function (require) { } }; - EQFilter.prototype.disconnect = function() { + EQFilter.prototype.disconnect = function () { if (this.biquad) { this.biquad.disconnect(); } }; - EQFilter.prototype.dispose = function() { + EQFilter.prototype.dispose = function () { // remove reference form soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); diff --git a/src/errorHandler.js b/src/errorHandler.js index 14811348..3f00a700 100644 --- a/src/errorHandler.js +++ b/src/errorHandler.js @@ -20,7 +20,7 @@ define(function () { @property {String} failedPath path to the file that failed to load @return {Error} returns a custom Error object */ - var CustomError = function(name, errorTrace, failedPath) { + var CustomError = function (name, errorTrace, failedPath) { var err = new Error(); var tempStack, splitStack; @@ -31,7 +31,7 @@ define(function () { // only print the part of the stack trace that refers to the user code: var splitStack = tempStack.split('\n'); - splitStack = splitStack.filter(function(ln) { + splitStack = splitStack.filter(function (ln) { return !ln.match(/(p5.|native code|globalInit)/g); }); err.stack = splitStack.join('\n'); diff --git a/src/fft.js b/src/fft.js index 77c73796..0276008b 100644 --- a/src/fft.js +++ b/src/fft.js @@ -1,6 +1,6 @@ 'use strict'; -define(function(require) { +define(function (require) { var p5sound = require('master'); /** @@ -87,30 +87,30 @@ define(function(require) { * } * */ - p5.FFT = function(smoothing, bins) { + p5.FFT = function (smoothing, bins) { this.input = this.analyser = p5sound.audiocontext.createAnalyser(); Object.defineProperties(this, { bins: { - get: function() { + get: function () { return this.analyser.fftSize / 2; }, - set: function(b) { + set: function (b) { this.analyser.fftSize = b * 2; }, configurable: true, - enumerable: true + enumerable: true, }, smoothing: { - get: function() { + get: function () { return this.analyser.smoothingTimeConstant; }, - set: function(s) { + set: function (s) { this.analyser.smoothingTimeConstant = s; }, configurable: true, - enumerable: true - } + enumerable: true, + }, }); // set default smoothing and bins @@ -142,7 +142,7 @@ define(function(require) { * @for p5.FFT * @param {Object} [source] p5.sound object (or web audio API source node) */ - p5.FFT.prototype.setInput = function(source) { + p5.FFT.prototype.setInput = function (source) { if (!source) { p5sound.fftMeter.connect(this.analyser); } else { @@ -172,7 +172,7 @@ define(function(require) { * over time. Array length = bins. * */ - p5.FFT.prototype.waveform = function() { + p5.FFT.prototype.waveform = function () { var bins, mode, normalArray; for (var i = 0; i < arguments.length; i++) { @@ -271,7 +271,7 @@ define(function(require) { * * */ - p5.FFT.prototype.analyze = function() { + p5.FFT.prototype.analyze = function () { var mode; for (var i = 0; i < arguments.length; i++) { @@ -326,7 +326,7 @@ define(function(require) { * 0 and 255. * */ - p5.FFT.prototype.getEnergy = function(frequency1, frequency2) { + p5.FFT.prototype.getEnergy = function (frequency1, frequency2) { var nyquist = p5sound.audiocontext.sampleRate / 2; if (frequency1 === 'bass') { @@ -350,7 +350,7 @@ define(function(require) { throw 'invalid input for getEnergy()'; } else if (!frequency2) { // if only one parameter: - var index = Math.round(frequency1 / nyquist * this.freqDomain.length); + var index = Math.round((frequency1 / nyquist) * this.freqDomain.length); return this.freqDomain[index]; } else if (frequency1 && frequency2) { // if two parameters: @@ -360,8 +360,12 @@ define(function(require) { frequency2 = frequency1; frequency1 = swap; } - var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length); - var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length); + var lowIndex = Math.round( + (frequency1 / nyquist) * this.freqDomain.length + ); + var highIndex = Math.round( + (frequency2 / nyquist) * this.freqDomain.length + ); var total = 0; var numFrequencies = 0; @@ -379,7 +383,7 @@ define(function(require) { }; // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated... - p5.FFT.prototype.getFreq = function(freq1, freq2) { + p5.FFT.prototype.getFreq = function (freq1, freq2) { console.log('getFreq() is deprecated. Please use getEnergy() instead.'); var x = this.getEnergy(freq1, freq2); return x; @@ -450,7 +454,7 @@ define(function(require) { *} * */ - p5.FFT.prototype.getCentroid = function() { + p5.FFT.prototype.getCentroid = function () { var nyquist = p5sound.audiocontext.sampleRate / 2; var cumulative_sum = 0; var centroid_normalization = 0; @@ -478,14 +482,14 @@ define(function(require) { * @param {Number} smoothing 0.0 < smoothing < 1.0. * Defaults to 0.8. */ - p5.FFT.prototype.smooth = function(s) { + p5.FFT.prototype.smooth = function (s) { if (typeof s !== 'undefined') { this.smoothing = s; } return this.smoothing; }; - p5.FFT.prototype.dispose = function() { + p5.FFT.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -508,7 +512,7 @@ define(function(require) { * @param {Number} N Number of returned frequency groups * @return {Array} linearAverages Array of average amplitude values for each group */ - p5.FFT.prototype.linAverages = function(N) { + p5.FFT.prototype.linAverages = function (N) { var N = N || 16; // This prevents undefined, null or 0 values of N var spectrum = this.freqDomain; @@ -548,7 +552,7 @@ define(function(require) { * @param {Array} octaveBands Array of Octave Bands objects for grouping * @return {Array} logAverages Array of average amplitude values for each group */ - p5.FFT.prototype.logAverages = function(octaveBands) { + p5.FFT.prototype.logAverages = function (octaveBands) { var nyquist = p5sound.audiocontext.sampleRate / 2; var spectrum = this.freqDomain; var spectrumLength = spectrum.length; @@ -560,7 +564,7 @@ define(function(require) { for (var specIndex = 0; specIndex < spectrumLength; specIndex++) { var specIndexFrequency = Math.round( - specIndex * nyquist / this.freqDomain.length + (specIndex * nyquist) / this.freqDomain.length ); // Increase the group index if the current frequency exceeds the limits of the band @@ -591,7 +595,7 @@ define(function(require) { * @param {Number} fCtr0 Minimum central frequency for the lowest band * @return {Array} octaveBands Array of octave band objects with their bounds */ - p5.FFT.prototype.getOctaveBands = function(N, fCtr0) { + p5.FFT.prototype.getOctaveBands = function (N, fCtr0) { var N = N || 3; // Default to 1/3 Octave Bands var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz @@ -599,7 +603,7 @@ define(function(require) { var lastFrequencyBand = { lo: fCtr0 / Math.pow(2, 1 / (2 * N)), ctr: fCtr0, - hi: fCtr0 * Math.pow(2, 1 / (2 * N)) + hi: fCtr0 * Math.pow(2, 1 / (2 * N)), }; octaveBands.push(lastFrequencyBand); @@ -618,22 +622,22 @@ define(function(require) { }; // helper methods to convert type from float (dB) to int (0-255) - var freqToFloat = function(fft) { + var freqToFloat = function (fft) { if (fft.freqDomain instanceof Float32Array === false) { fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount); } }; - var freqToInt = function(fft) { + var freqToInt = function (fft) { if (fft.freqDomain instanceof Uint8Array === false) { fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount); } }; - var timeToFloat = function(fft) { + var timeToFloat = function (fft) { if (fft.timeDomain instanceof Float32Array === false) { fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount); } }; - var timeToInt = function(fft) { + var timeToInt = function (fft) { if (fft.timeDomain instanceof Uint8Array === false) { fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount); } diff --git a/src/filter.js b/src/filter.js index e0ed60d8..1d43d4b7 100644 --- a/src/filter.js +++ b/src/filter.js @@ -30,70 +30,69 @@ define(function (require) { * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass' * @example *

- * let fft, noise, filter; - * - * function setup() { - * let cnv = createCanvas(100,100); - * cnv.mousePressed(makeNoise); - * fill(255, 0, 255); - * - * filter = new p5.BandPass(); - * noise = new p5.Noise(); - * noise.disconnect(); - * noise.connect(filter); - * - * fft = new p5.FFT(); - * } - * - * function draw() { - * background(220); - * - * // set the BandPass frequency based on mouseX - * let freq = map(mouseX, 0, width, 20, 10000); - * freq = constrain(freq, 0, 22050); - * filter.freq(freq); - * // give the filter a narrow band (lower res = wider bandpass) - * filter.res(50); - * - * // draw filtered spectrum - * let spectrum = fft.analyze(); - * noStroke(); - * for (let i = 0; i < spectrum.length; i++) { - * let x = map(i, 0, spectrum.length, 0, width); - * let h = -height + map(spectrum[i], 0, 255, height, 0); - * rect(x, height, width/spectrum.length, h); - * } - * if (!noise.started) { - * text('tap here and drag to change frequency', 10, 20, width - 20); - * } else { - * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20); - * } - * } - * - * function makeNoise() { - * // see also: `userStartAudio()` - * noise.start(); - * noise.amp(0.5, 0.2); - * } - * - * function mouseReleased() { - * noise.amp(0, 0.2); - * } - * + * let fft, noise, filter; + * + * function setup() { + * let cnv = createCanvas(100,100); + * cnv.mousePressed(makeNoise); + * fill(255, 0, 255); + * + * filter = new p5.BandPass(); + * noise = new p5.Noise(); + * noise.disconnect(); + * noise.connect(filter); + * + * fft = new p5.FFT(); + * } + * + * function draw() { + * background(220); + * + * // set the BandPass frequency based on mouseX + * let freq = map(mouseX, 0, width, 20, 10000); + * freq = constrain(freq, 0, 22050); + * filter.freq(freq); + * // give the filter a narrow band (lower res = wider bandpass) + * filter.res(50); + * + * // draw filtered spectrum + * let spectrum = fft.analyze(); + * noStroke(); + * for (let i = 0; i < spectrum.length; i++) { + * let x = map(i, 0, spectrum.length, 0, width); + * let h = -height + map(spectrum[i], 0, 255, height, 0); + * rect(x, height, width/spectrum.length, h); + * } + * if (!noise.started) { + * text('tap here and drag to change frequency', 10, 20, width - 20); + * } else { + * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20); + * } + * } + * + * function makeNoise() { + * // see also: `userStartAudio()` + * noise.start(); + * noise.amp(0.5, 0.2); + * } + * + * function mouseReleased() { + * noise.amp(0, 0.2); + * } + * *
*/ p5.Filter = function (type) { - Effect.call(this); //add extend Effect by adding a Biquad Filter /** - * The p5.Filter is built with a - * - * Web Audio BiquadFilter Node. - * - * @property {DelayNode} biquadFilter - */ + * The p5.Filter is built with a + * + * Web Audio BiquadFilter Node. + * + * @property {DelayNode} biquadFilter + */ this.biquad = this.ac.createBiquadFilter(); @@ -111,7 +110,6 @@ define(function (require) { }; p5.Filter.prototype = Object.create(Effect.prototype); - /** * Filter an audio signal according to a set * of filter parameters. @@ -122,12 +120,11 @@ define(function (require) { * @param {Number} [res] Resonance/Width of the filter frequency * from 0.001 to 1000 */ - p5.Filter.prototype.process = function(src, freq, res, time) { + p5.Filter.prototype.process = function (src, freq, res, time) { src.connect(this.input); this.set(freq, res, time); }; - /** * Set the frequency and the resonance of the filter. * @@ -137,7 +134,7 @@ define(function (require) { * @param {Number} [timeFromNow] schedule this event to happen * seconds from now */ - p5.Filter.prototype.set = function(freq, res, time) { + p5.Filter.prototype.set = function (freq, res, time) { if (freq) { this.freq(freq, time); } @@ -157,14 +154,19 @@ define(function (require) { * seconds from now * @return {Number} value Returns the current frequency value */ - p5.Filter.prototype.freq = function(freq, time) { + p5.Filter.prototype.freq = function (freq, time) { var t = time || 0; if (freq <= 0) { freq = 1; } if (typeof freq === 'number') { - this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t); + this.biquad.frequency.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.biquad.frequency.exponentialRampToValueAtTime( + freq, + this.ac.currentTime + 0.02 + t + ); } else if (freq) { freq.connect(this.biquad.frequency); } @@ -182,12 +184,15 @@ define(function (require) { * seconds from now * @return {Number} value Returns the current res value */ - p5.Filter.prototype.res = function(res, time) { + p5.Filter.prototype.res = function (res, time) { var t = time || 0; if (typeof res === 'number') { this.biquad.Q.value = res; this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t); + this.biquad.Q.linearRampToValueAtTime( + res, + this.ac.currentTime + 0.02 + t + ); } else if (res) { res.connect(this.biquad.Q); } @@ -204,26 +209,28 @@ define(function (require) { * @param {Number} gain * @return {Number} Returns the current or updated gain value */ - p5.Filter.prototype.gain = function(gain, time) { + p5.Filter.prototype.gain = function (gain, time) { var t = time || 0; if (typeof gain === 'number') { this.biquad.gain.value = gain; this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t); + this.biquad.gain.linearRampToValueAtTime( + gain, + this.ac.currentTime + 0.02 + t + ); } else if (gain) { gain.connect(this.biquad.gain); } return this.biquad.gain.value; }; - /** * Toggle function. Switches between the specified type and allpass * * @method toggle * @return {boolean} [Toggle value] */ - p5.Filter.prototype.toggle = function() { + p5.Filter.prototype.toggle = function () { this._on = !this._on; if (this._on === true) { @@ -244,12 +251,12 @@ define(function (require) { * @method setType * @param {String} t */ - p5.Filter.prototype.setType = function(t) { + p5.Filter.prototype.setType = function (t) { this.biquad.type = t; this._untoggledType = this.biquad.type; }; - p5.Filter.prototype.dispose = function() { + p5.Filter.prototype.dispose = function () { // remove reference from soundArray Effect.prototype.dispose.apply(this); if (this.biquad) { @@ -268,7 +275,7 @@ define(function (require) { * @constructor * @extends p5.Filter */ - p5.LowPass = function() { + p5.LowPass = function () { p5.Filter.call(this, 'lowpass'); }; p5.LowPass.prototype = Object.create(p5.Filter.prototype); @@ -283,7 +290,7 @@ define(function (require) { * @constructor * @extends p5.Filter */ - p5.HighPass = function() { + p5.HighPass = function () { p5.Filter.call(this, 'highpass'); }; p5.HighPass.prototype = Object.create(p5.Filter.prototype); @@ -298,7 +305,7 @@ define(function (require) { * @constructor * @extends p5.Filter */ - p5.BandPass = function() { + p5.BandPass = function () { p5.Filter.call(this, 'bandpass'); }; p5.BandPass.prototype = Object.create(p5.Filter.prototype); diff --git a/src/gain.js b/src/gain.js index 628552b1..ce1698b5 100644 --- a/src/gain.js +++ b/src/gain.js @@ -71,7 +71,7 @@ define(function (require) { * */ - p5.Gain = function() { + p5.Gain = function () { this.ac = p5sound.audiocontext; this.input = this.ac.createGain(); @@ -94,8 +94,7 @@ define(function (require) { * output. */ - - p5.Gain.prototype.setInput = function(src) { + p5.Gain.prototype.setInput = function (src) { src.connect(this.input); }; @@ -106,7 +105,7 @@ define(function (require) { * @for p5.Gain * @param {Object} unit */ - p5.Gain.prototype.connect = function(unit) { + p5.Gain.prototype.connect = function (unit) { var u = unit || p5.soundOut.input; this.output.connect(u.input ? u.input : u); }; @@ -117,7 +116,7 @@ define(function (require) { * @method disconnect * @for p5.Gain */ - p5.Gain.prototype.disconnect = function() { + p5.Gain.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } @@ -133,7 +132,7 @@ define(function (require) { * @param {Number} [timeFromNow] schedule this event to happen * seconds from now */ - p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) { + p5.Gain.prototype.amp = function (vol, rampTime, tFromNow) { var rampTime = rampTime || 0; var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; @@ -143,7 +142,7 @@ define(function (require) { this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); }; - p5.Gain.prototype.dispose = function() { + p5.Gain.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -156,5 +155,4 @@ define(function (require) { delete this.input; } }; - }); diff --git a/src/helpers.js b/src/helpers.js index f829e9db..608f91b5 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -16,11 +16,10 @@ define(function (require) { * @method sampleRate * @return {Number} samplerate samples per second */ - p5.prototype.sampleRate = function() { + p5.prototype.sampleRate = function () { return p5sound.audiocontext.sampleRate; }; - /** * Returns the closest MIDI note value for * a given frequency. @@ -30,9 +29,9 @@ define(function (require) { * above Middle C is 440Hz * @return {Number} MIDI note value */ - p5.prototype.freqToMidi = function(f) { - var mathlog2 = Math.log(f/440) / Math.log(2); - var m = Math.round(12*mathlog2)+69; + p5.prototype.freqToMidi = function (f) { + var mathlog2 = Math.log(f / 440) / Math.log(2); + var m = Math.round(12 * mathlog2) + 69; return m; }; @@ -80,21 +79,21 @@ define(function (require) { * } * */ - var midiToFreq = p5.prototype.midiToFreq = function(m) { - return 440 * Math.pow(2, (m-69)/12.0); - }; + var midiToFreq = (p5.prototype.midiToFreq = function (m) { + return 440 * Math.pow(2, (m - 69) / 12.0); + }); // This method converts ANSI notes specified as a string "C4", "Eb3" to a frequency - var noteToFreq = function(note) { + var noteToFreq = function (note) { if (typeof note !== 'string') { return note; } - var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31}; - var value = wholeNotes[ note[0].toUpperCase() ]; + var wholeNotes = { A: 21, B: 23, C: 24, D: 26, E: 28, F: 29, G: 31 }; + var value = wholeNotes[note[0].toUpperCase()]; var octave = ~~note.slice(-1); - value += 12 * (octave -1); + value += 12 * (octave - 1); - switch(note[1]) { + switch (note[1]) { case '#': value += 1; break; @@ -136,13 +135,13 @@ define(function (require) { * } * */ - p5.prototype.soundFormats = function() { + p5.prototype.soundFormats = function () { // reset extensions array p5sound.extensions = []; // add extensions for (var i = 0; i < arguments.length; i++) { arguments[i] = arguments[i].toLowerCase(); - if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) { + if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) { p5sound.extensions.push(arguments[i]); } else { throw arguments[i] + ' is not a valid sound format!'; @@ -150,7 +149,7 @@ define(function (require) { } }; - p5.prototype.disposeSound = function() { + p5.prototype.disposeSound = function () { for (var i = 0; i < p5sound.soundArray.length; i++) { p5sound.soundArray[i].dispose(); } @@ -160,7 +159,7 @@ define(function (require) { // Oscillators etc when sketch ends p5.prototype.registerMethod('remove', p5.prototype.disposeSound); - p5.prototype._checkFileFormats = function(paths) { + p5.prototype._checkFileFormats = function (paths) { var path; // if path is a single string, check to see if extension is provided if (typeof paths === 'string') { @@ -168,14 +167,13 @@ define(function (require) { // see if extension is provided var extTest = path.split('.').pop(); // if an extension is provided... - if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) { + if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(extTest) > -1) { if (p5.prototype.isFileSupported(extTest)) { path = path; - } - else { + } else { var pathSplit = path.split('.'); var pathCore = pathSplit[pathSplit.length - 1]; - for (var i = 0; ip5.Panner3D - Constructs a Spatial Panner
-// * p5.Listener3D - Constructs a Spatial Listener
-// * -// * @class listener -// * @constructor -// * @return {Object} p5.Listener3D Object -// * -// * @param {Web Audio Node} listener Web Audio Spatial Panning Node -// * @param {AudioParam} listener.panningModel "equal power" or "HRTF" -// * @param {AudioParam} listener.distanceModel "linear", "inverse", or "exponential" -// * @param {String} [type] [Specify construction of a spatial panner or listener] -// */ - - p5.Listener3D = function(type) { - this.ac = p5sound.audiocontext; - this.listener = this.ac.listener; - }; + // /** + // * listener is a class that can construct both a Spatial Panner + // * and a Spatial Listener. The panner is based on the + // * Web Audio Spatial Panner Node + // * https://www.w3.org/TR/webaudio/#the-listenernode-interface + // * This panner is a spatial processing node that allows audio to be positioned + // * and oriented in 3D space. + // * + // * The Listener modifies the properties of the Audio Context Listener. + // * Both objects types use the same methods. The default is a spatial panner. + // * + // * p5.Panner3D - Constructs a Spatial Panner
+ // * p5.Listener3D - Constructs a Spatial Listener
+ // * + // * @class listener + // * @constructor + // * @return {Object} p5.Listener3D Object + // * + // * @param {Web Audio Node} listener Web Audio Spatial Panning Node + // * @param {AudioParam} listener.panningModel "equal power" or "HRTF" + // * @param {AudioParam} listener.distanceModel "linear", "inverse", or "exponential" + // * @param {String} [type] [Specify construction of a spatial panner or listener] + // */ -// /** -// * Connect an audio sorce -// * @param {Object} src Input source -// */ - p5.Listener3D.prototype.process = function(src) { + p5.Listener3D = function (type) { + this.ac = p5sound.audiocontext; + this.listener = this.ac.listener; + }; + + // /** + // * Connect an audio sorce + // * @param {Object} src Input source + // */ + p5.Listener3D.prototype.process = function (src) { src.connect(this.input); - } -// /** -// * Set the X,Y,Z position of the Panner -// * @param {[Number]} xVal -// * @param {[Number]} yVal -// * @param {[Number]} zVal -// * @param {[Number]} time -// * @return {[Array]} [Updated x, y, z values as an array] -// */ - p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) { - this.positionX(xVal,time); - this.positionY(yVal,time); - this.positionZ(zVal,time); - return [this.listener.positionX.value, - this.listener.positionY.value, - this.listener.positionZ.value]; + }; + // /** + // * Set the X,Y,Z position of the Panner + // * @param {[Number]} xVal + // * @param {[Number]} yVal + // * @param {[Number]} zVal + // * @param {[Number]} time + // * @return {[Array]} [Updated x, y, z values as an array] + // */ + p5.Listener3D.prototype.position = function (xVal, yVal, zVal, time) { + this.positionX(xVal, time); + this.positionY(yVal, time); + this.positionZ(zVal, time); + return [ + this.listener.positionX.value, + this.listener.positionY.value, + this.listener.positionZ.value, + ]; }; -// /** -// * Getter and setter methods for position coordinates -// * @return {Number} [updated coordinate value] -// */ - p5.Listener3D.prototype.positionX = function(xVal, time) { + // /** + // * Getter and setter methods for position coordinates + // * @return {Number} [updated coordinate value] + // */ + p5.Listener3D.prototype.positionX = function (xVal, time) { var t = time || 0; if (typeof xVal === 'number') { this.listener.positionX.value = xVal; - this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t); + this.listener.positionX.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.positionX.linearRampToValueAtTime( + xVal, + this.ac.currentTime + 0.02 + t + ); } else if (xVal) { xVal.connect(this.listener.positionX); } return this.listener.positionX.value; }; - p5.Listener3D.prototype.positionY = function(yVal, time) { + p5.Listener3D.prototype.positionY = function (yVal, time) { var t = time || 0; if (typeof yVal === 'number') { this.listener.positionY.value = yVal; - this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t); + this.listener.positionY.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.positionY.linearRampToValueAtTime( + yVal, + this.ac.currentTime + 0.02 + t + ); } else if (yVal) { yVal.connect(this.listener.positionY); } return this.listener.positionY.value; }; - p5.Listener3D.prototype.positionZ = function(zVal, time) { + p5.Listener3D.prototype.positionZ = function (zVal, time) { var t = time || 0; if (typeof zVal === 'number') { this.listener.positionZ.value = zVal; - this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t); + this.listener.positionZ.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.positionZ.linearRampToValueAtTime( + zVal, + this.ac.currentTime + 0.02 + t + ); } else if (zVal) { zVal.connect(this.listener.positionZ); } return this.listener.positionZ.value; }; -// cannot define method when class definition is commented -// /** -// * Overrides the listener orient() method because Listener has slightly -// * different params. In human terms, Forward vectors are the direction the -// * nose is pointing. Up vectors are the direction of the top of the head. -// * -// * @method orient -// * @param {Number} xValF Forward vector X direction -// * @param {Number} yValF Forward vector Y direction -// * @param {Number} zValF Forward vector Z direction -// * @param {Number} xValU Up vector X direction -// * @param {Number} yValU Up vector Y direction -// * @param {Number} zValU Up vector Z direction -// * @param {Number} time -// * @return {Array} All orienation params -// */ - p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, - xValU, yValU, zValU, time) { + // cannot define method when class definition is commented + // /** + // * Overrides the listener orient() method because Listener has slightly + // * different params. In human terms, Forward vectors are the direction the + // * nose is pointing. Up vectors are the direction of the top of the head. + // * + // * @method orient + // * @param {Number} xValF Forward vector X direction + // * @param {Number} yValF Forward vector Y direction + // * @param {Number} zValF Forward vector Z direction + // * @param {Number} xValU Up vector X direction + // * @param {Number} yValU Up vector Y direction + // * @param {Number} zValU Up vector Z direction + // * @param {Number} time + // * @return {Array} All orienation params + // */ + p5.Listener3D.prototype.orient = function ( + xValF, + yValF, + zValF, + xValU, + yValU, + zValU, + time + ) { + if (arguments.length === 3 || arguments.length === 4) { + time = arguments[3]; + this.orientForward(xValF, yValF, zValF, time); + } else if (arguments.length === 6 || arguments === 7) { + this.orientForward(xValF, yValF, zValF); + this.orientUp(xValU, yValU, zValU, time); + } - if (arguments.length === 3 || arguments.length === 4) { - time = arguments[3]; - this.orientForward(xValF, yValF, zValF, time); - } else if (arguments.length === 6 || arguments === 7) { - this.orientForward(xValF, yValF, zValF); - this.orientUp(xValU, yValU, zValU, time); - } - - 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]; + 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, + ]; }; + p5.Listener3D.prototype.orientForward = function (xValF, yValF, zValF, time) { + this.forwardX(xValF, time); + this.forwardY(yValF, time); + this.forwardZ(zValF, time); - p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) { - this.forwardX(xValF,time); - this.forwardY(yValF,time); - this.forwardZ(zValF,time); - - return [this.listener.forwardX, - this.listener.forwardY, - this.listener.forwardZ]; + return [ + this.listener.forwardX, + this.listener.forwardY, + this.listener.forwardZ, + ]; }; - p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) { - this.upX(xValU,time); - this.upY(yValU,time); - this.upZ(zValU,time); + p5.Listener3D.prototype.orientUp = function (xValU, yValU, zValU, time) { + this.upX(xValU, time); + this.upY(yValU, time); + this.upZ(zValU, time); - return [this.listener.upX, - this.listener.upY, - this.listener.upZ]; + return [this.listener.upX, this.listener.upY, this.listener.upZ]; }; -// /** -// * Getter and setter methods for orient coordinates -// * @return {Number} [updated coordinate value] -// */ - p5.Listener3D.prototype.forwardX = function(xVal, time) { + // /** + // * Getter and setter methods for orient coordinates + // * @return {Number} [updated coordinate value] + // */ + p5.Listener3D.prototype.forwardX = function (xVal, time) { var t = time || 0; if (typeof xVal === 'number') { this.listener.forwardX.value = xVal; - this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t); + this.listener.forwardX.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.forwardX.linearRampToValueAtTime( + xVal, + this.ac.currentTime + 0.02 + t + ); } else if (xVal) { xVal.connect(this.listener.forwardX); } return this.listener.forwardX.value; }; - p5.Listener3D.prototype.forwardY = function(yVal, time) { + p5.Listener3D.prototype.forwardY = function (yVal, time) { var t = time || 0; if (typeof yVal === 'number') { this.listener.forwardY.value = yVal; - this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t); + this.listener.forwardY.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.forwardY.linearRampToValueAtTime( + yVal, + this.ac.currentTime + 0.02 + t + ); } else if (yVal) { yVal.connect(this.listener.forwardY); } return this.listener.forwardY.value; }; - p5.Listener3D.prototype.forwardZ = function(zVal, time) { + p5.Listener3D.prototype.forwardZ = function (zVal, time) { var t = time || 0; if (typeof zVal === 'number') { this.listener.forwardZ.value = zVal; - this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t); + this.listener.forwardZ.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.listener.forwardZ.linearRampToValueAtTime( + zVal, + this.ac.currentTime + 0.02 + t + ); } else if (zVal) { zVal.connect(this.listener.forwardZ); } return this.listener.forwardZ.value; }; - p5.Listener3D.prototype.upX = function(xVal, time) { + p5.Listener3D.prototype.upX = function (xVal, time) { var t = time || 0; if (typeof xVal === 'number') { this.listener.upX.value = xVal; this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t); + this.listener.upX.linearRampToValueAtTime( + xVal, + this.ac.currentTime + 0.02 + t + ); } else if (xVal) { xVal.connect(this.listener.upX); } return this.listener.upX.value; }; - p5.Listener3D.prototype.upY = function(yVal, time) { + p5.Listener3D.prototype.upY = function (yVal, time) { var t = time || 0; if (typeof yVal === 'number') { this.listener.upY.value = yVal; this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t); + this.listener.upY.linearRampToValueAtTime( + yVal, + this.ac.currentTime + 0.02 + t + ); } else if (yVal) { yVal.connect(this.listener.upY); } return this.listener.upY.value; }; - p5.Listener3D.prototype.upZ = function(zVal, time) { + p5.Listener3D.prototype.upZ = function (zVal, time) { var t = time || 0; if (typeof zVal === 'number') { this.listener.upZ.value = zVal; this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t); + this.listener.upZ.linearRampToValueAtTime( + zVal, + this.ac.currentTime + 0.02 + t + ); } else if (zVal) { zVal.connect(this.listener.upZ); } return this.listener.upZ.value; }; - - return p5.Listener3D; -}); \ No newline at end of file + return p5.Listener3D; +}); diff --git a/src/looper.js b/src/looper.js index c136fe91..4fc52d13 100644 --- a/src/looper.js +++ b/src/looper.js @@ -1,6 +1,6 @@ 'use strict'; -define(function(require) { +define(function (require) { var p5sound = require('master'); var BPM = 120; @@ -14,7 +14,7 @@ define(function(require) { * @param {Number} BPM Beats Per Minute * @param {Number} rampTime Seconds from now */ - p5.prototype.setBPM = function(bpm, rampTime) { + p5.prototype.setBPM = function (bpm, rampTime) { BPM = bpm; for (var i in p5sound.parts) { if (p5sound.parts[i]) { @@ -85,7 +85,7 @@ define(function(require) { * } * */ - p5.Phrase = function(name, callback, sequence) { + p5.Phrase = function (name, callback, sequence) { this.phraseStep = 0; this.name = name; this.callback = callback; @@ -154,7 +154,7 @@ define(function(require) { * } * */ - p5.Part = function(steps, bLength) { + p5.Part = function (steps, bLength) { this.length = steps || 0; // how many beats this.partStep = 0; this.phrases = []; @@ -167,7 +167,7 @@ define(function(require) { this.metro.beatLength(this.tatums); this.metro.setBPM(BPM); p5sound.parts.push(this); - this.callback = function() {}; + this.callback = function () {}; }; /** @@ -178,7 +178,7 @@ define(function(require) { * @param {Number} BPM Beats Per Minute * @param {Number} [rampTime] Seconds from now */ - p5.Part.prototype.setBPM = function(tempo, rampTime) { + p5.Part.prototype.setBPM = function (tempo, rampTime) { this.metro.setBPM(tempo, rampTime); }; @@ -189,7 +189,7 @@ define(function(require) { * @for p5.Part * @return {Number} */ - p5.Part.prototype.getBPM = function() { + p5.Part.prototype.getBPM = function () { return this.metro.getBPM(); }; @@ -202,7 +202,7 @@ define(function(require) { * @for p5.Part * @param {Number} [time] seconds from now */ - p5.Part.prototype.start = function(time) { + p5.Part.prototype.start = function (time) { if (!this.isPlaying) { this.isPlaying = true; this.metro.resetSync(this); @@ -220,10 +220,10 @@ define(function(require) { * @for p5.Part * @param {Number} [time] seconds from now */ - p5.Part.prototype.loop = function(time) { + p5.Part.prototype.loop = function (time) { this.looping = true; // rest onended function - this.onended = function() { + this.onended = function () { this.partStep = 0; }; var t = time || 0; @@ -236,10 +236,10 @@ define(function(require) { * @method noLoop * @for p5.Part */ - p5.Part.prototype.noLoop = function() { + p5.Part.prototype.noLoop = function () { this.looping = false; // rest onended function - this.onended = function() { + this.onended = function () { this.stop(); }; }; @@ -251,7 +251,7 @@ define(function(require) { * @for p5.Part * @param {Number} [time] seconds from now */ - p5.Part.prototype.stop = function(time) { + p5.Part.prototype.stop = function (time) { this.partStep = 0; this.pause(time); }; @@ -264,7 +264,7 @@ define(function(require) { * @for p5.Part * @param {Number} time seconds from now */ - p5.Part.prototype.pause = function(time) { + p5.Part.prototype.pause = function (time) { this.isPlaying = false; var t = time || 0; this.metro.stop(t); @@ -277,7 +277,7 @@ define(function(require) { * @for p5.Part * @param {p5.Phrase} phrase reference to a p5.Phrase */ - p5.Part.prototype.addPhrase = function(name, callback, array) { + p5.Part.prototype.addPhrase = function (name, callback, array) { var p; if (arguments.length === 3) { p = new p5.Phrase(name, callback, array); @@ -301,7 +301,7 @@ define(function(require) { * @for p5.Part * @param {String} phraseName */ - p5.Part.prototype.removePhrase = function(name) { + p5.Part.prototype.removePhrase = function (name) { for (var i in this.phrases) { if (this.phrases[i].name === name) { this.phrases.splice(i, 1); @@ -317,7 +317,7 @@ define(function(require) { * @for p5.Part * @param {String} phraseName */ - p5.Part.prototype.getPhrase = function(name) { + p5.Part.prototype.getPhrase = function (name) { for (var i in this.phrases) { if (this.phrases[i].name === name) { return this.phrases[i]; @@ -334,7 +334,7 @@ define(function(require) { * @param {Array} sequence Array of values to pass into the callback * at each step of the phrase. */ - p5.Part.prototype.replaceSequence = function(name, array) { + p5.Part.prototype.replaceSequence = function (name, array) { for (var i in this.phrases) { if (this.phrases[i].name === name) { this.phrases[i].sequence = array; @@ -342,7 +342,7 @@ define(function(require) { } }; - p5.Part.prototype.incrementStep = function(time) { + p5.Part.prototype.incrementStep = function (time) { if (this.partStep < this.length - 1) { this.callback(time); this.partStep += 1; @@ -363,11 +363,10 @@ define(function(require) { * you want to fire * on every beat/tatum. */ - p5.Part.prototype.onStep = function(callback) { + p5.Part.prototype.onStep = function (callback) { this.callback = callback; }; - // =============== // p5.Score // =============== @@ -382,7 +381,7 @@ define(function(require) { * @constructor * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence. */ - p5.Score = function() { + p5.Score = function () { // for all of the arguments this.parts = []; this.currentPart = 0; @@ -392,7 +391,7 @@ define(function(require) { if (arguments[i] && this.parts[i]) { this.parts[i] = arguments[i]; this.parts[i].nextPart = this.parts[i + 1]; - this.parts[i].onended = function() { + this.parts[i].onended = function () { thisScore.resetPart(i); playNextPart(thisScore); }; @@ -401,12 +400,12 @@ define(function(require) { this.looping = false; }; - p5.Score.prototype.onended = function() { + p5.Score.prototype.onended = function () { if (this.looping) { // this.resetParts(); this.parts[0].start(); } else { - this.parts[this.parts.length - 1].onended = function() { + this.parts[this.parts.length - 1].onended = function () { this.stop(); this.resetParts(); }; @@ -420,7 +419,7 @@ define(function(require) { * @method start * @for p5.Score */ - p5.Score.prototype.start = function() { + p5.Score.prototype.start = function () { this.parts[this.currentPart].start(); this.scoreStep = 0; }; @@ -431,7 +430,7 @@ define(function(require) { * @method stop * @for p5.Score */ - p5.Score.prototype.stop = function() { + p5.Score.prototype.stop = function () { this.parts[this.currentPart].stop(); this.currentPart = 0; this.scoreStep = 0; @@ -443,7 +442,7 @@ define(function(require) { * @method pause * @for p5.Score */ - p5.Score.prototype.pause = function() { + p5.Score.prototype.pause = function () { this.parts[this.currentPart].stop(); }; @@ -453,7 +452,7 @@ define(function(require) { * @method loop * @for p5.Score */ - p5.Score.prototype.loop = function() { + p5.Score.prototype.loop = function () { this.looping = true; this.start(); }; @@ -466,18 +465,18 @@ define(function(require) { * @method noLoop * @for p5.Score */ - p5.Score.prototype.noLoop = function() { + p5.Score.prototype.noLoop = function () { this.looping = false; }; - p5.Score.prototype.resetParts = function() { + p5.Score.prototype.resetParts = function () { var self = this; - this.parts.forEach(function(part) { + this.parts.forEach(function (part) { self.resetParts[part]; }); }; - p5.Score.prototype.resetPart = function(i) { + p5.Score.prototype.resetPart = function (i) { this.parts[i].stop(); this.parts[i].partStep = 0; for (var p in this.parts[i].phrases) { @@ -495,7 +494,7 @@ define(function(require) { * @param {Number} BPM Beats Per Minute * @param {Number} rampTime Seconds from now */ - p5.Score.prototype.setBPM = function(bpm, rampTime) { + p5.Score.prototype.setBPM = function (bpm, rampTime) { for (var i in this.parts) { if (this.parts[i]) { this.parts[i].setBPM(bpm, rampTime); @@ -514,5 +513,4 @@ define(function(require) { aScore.parts[aScore.currentPart].start(); } } - }); diff --git a/src/master.js b/src/master.js index 1f229752..d66c0c10 100644 --- a/src/master.js +++ b/src/master.js @@ -1,9 +1,8 @@ 'use strict'; - define(['audiocontext'], function (audiocontext) { // Master contains the master sound output. - var Master = function() { + var Master = function () { this.input = audiocontext.createGain(); this.output = audiocontext.createGain(); @@ -52,7 +51,7 @@ define(['audiocontext'], function (audiocontext) { * @return {Number} Master amplitude (volume) for sound in this sketch. * Should be between 0.0 (silence) and 1.0. */ - p5.prototype.getMasterVolume = function() { + p5.prototype.getMasterVolume = function () { return p5sound.output.gain.value; }; @@ -82,7 +81,7 @@ define(['audiocontext'], function (audiocontext) { * @param {Number} [timeFromNow] Schedule this event to happen at * t seconds in the future */ - p5.prototype.masterVolume = function(vol, rampTime, tFromNow) { + p5.prototype.masterVolume = function (vol, rampTime, tFromNow) { if (typeof vol === 'number') { var rampTime = rampTime || 0; var tFromNow = tFromNow || 0; @@ -90,9 +89,11 @@ define(['audiocontext'], function (audiocontext) { var currentVol = p5sound.output.gain.value; p5sound.output.gain.cancelScheduledValues(now + tFromNow); p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow); - p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); - } - else if (vol) { + p5sound.output.gain.linearRampToValueAtTime( + vol, + now + tFromNow + rampTime + ); + } else if (vol) { vol.connect(p5sound.output.gain); } else { // return the Gain Node @@ -117,6 +118,5 @@ define(['audiocontext'], function (audiocontext) { p5.soundOut._silentNode.gain.value = 0; p5.soundOut._silentNode.connect(p5sound.audiocontext.destination); - return p5sound; }); diff --git a/src/metro.js b/src/metro.js index 3b670b95..18b31d9b 100644 --- a/src/metro.js +++ b/src/metro.js @@ -7,9 +7,9 @@ define(function (require) { // https://github.com/TONEnoTONE/Tone.js/ var Clock = require('Tone/core/Clock'); - p5.Metro = function() { + p5.Metro = function () { this.clock = new Clock({ - 'callback': this.ontick.bind(this) + callback: this.ontick.bind(this), }); this.syncedParts = []; this.bpm = 120; // gets overridden by p5.Part @@ -18,10 +18,10 @@ define(function (require) { this.prevTick = 0; this.tatumTime = 0; - this.tickCallback = function() {}; + this.tickCallback = function () {}; }; - p5.Metro.prototype.ontick = function(tickTime) { + p5.Metro.prototype.ontick = function (tickTime) { var elapsedTime = tickTime - this.prevTick; var secondsFromNow = tickTime - p5sound.audiocontext.currentTime; if (elapsedTime - this.tatumTime <= -0.02) { @@ -32,14 +32,17 @@ define(function (require) { // for all of the active things on the metro: var self = this; - this.syncedParts.forEach(function(thisPart) { + this.syncedParts.forEach(function (thisPart) { if (!thisPart.isPlaying) return; thisPart.incrementStep(secondsFromNow); // each synced source keeps track of its own beat number - thisPart.phrases.forEach(function(thisPhrase) { + thisPart.phrases.forEach(function (thisPhrase) { var phraseArray = thisPhrase.sequence; var bNum = self.metroTicks % phraseArray.length; - if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) { + if ( + phraseArray[bNum] !== 0 && + (self.metroTicks < phraseArray.length || !thisPhrase.looping) + ) { thisPhrase.callback(secondsFromNow, phraseArray[bNum]); } }); @@ -49,8 +52,8 @@ define(function (require) { } }; - p5.Metro.prototype.setBPM = function(bpm, rampTime) { - var beatTime = 60 / (bpm*this.tatums); + p5.Metro.prototype.setBPM = function (bpm, rampTime) { + var beatTime = 60 / (bpm * this.tatums); var now = p5sound.audiocontext.currentTime; this.tatumTime = beatTime; @@ -60,40 +63,39 @@ define(function (require) { this.bpm = bpm; }; - p5.Metro.prototype.getBPM = function() { - return this.clock.getRate() / this.tatums * 60; + p5.Metro.prototype.getBPM = function () { + return (this.clock.getRate() / this.tatums) * 60; }; - p5.Metro.prototype._init = function() { + p5.Metro.prototype._init = function () { this.metroTicks = 0; // this.setBPM(120); }; // clear existing synced parts, add only this one - p5.Metro.prototype.resetSync = function(part) { + p5.Metro.prototype.resetSync = function (part) { this.syncedParts = [part]; }; // push a new synced part to the array - p5.Metro.prototype.pushSync = function(part) { + p5.Metro.prototype.pushSync = function (part) { this.syncedParts.push(part); }; - p5.Metro.prototype.start = function(timeFromNow) { + p5.Metro.prototype.start = function (timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; this.clock.start(now + t); this.setBPM(this.bpm); }; - p5.Metro.prototype.stop = function(timeFromNow) { + p5.Metro.prototype.stop = function (timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; this.clock.stop(now + t); }; - p5.Metro.prototype.beatLength = function(tatums) { - this.tatums = 1/tatums / 4; // lowest possible division of a beat + p5.Metro.prototype.beatLength = function (tatums) { + this.tatums = 1 / tatums / 4; // lowest possible division of a beat }; - }); diff --git a/src/monosynth.js b/src/monosynth.js index e6e2f567..13f25630 100644 --- a/src/monosynth.js +++ b/src/monosynth.js @@ -1,6 +1,5 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); var AudioVoice = require('audioVoice'); var noteToFreq = require('helpers').noteToFreq; @@ -8,42 +7,42 @@ define(function (require) { var DEFAULT_SUSTAIN = 0.15; /** - * A MonoSynth is used as a single voice for sound synthesis. - * This is a class to be used in conjunction with the PolySynth - * class. Custom synthetisers should be built inheriting from - * this class. - * - * @class p5.MonoSynth - * @constructor - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * textAlign(CENTER); - * text('tap to play', width/2, height/2); - * - * monoSynth = new p5.MonoSynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * let note = random(['Fb4', 'G4']); - * // note velocity (volume, from 0 to 1) - * let velocity = random(); - * // time from now (in seconds) - * let time = 0; - * // note duration (in seconds) - * let dur = 1/6; - * - * monoSynth.play(note, velocity, time, dur); - * } - *
- **/ + * A MonoSynth is used as a single voice for sound synthesis. + * This is a class to be used in conjunction with the PolySynth + * class. Custom synthetisers should be built inheriting from + * this class. + * + * @class p5.MonoSynth + * @constructor + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * textAlign(CENTER); + * text('tap to play', width/2, height/2); + * + * monoSynth = new p5.MonoSynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * let note = random(['Fb4', 'G4']); + * // note velocity (volume, from 0 to 1) + * let velocity = random(); + * // time from now (in seconds) + * let time = 0; + * // note duration (in seconds) + * let dur = 1/6; + * + * monoSynth.play(note, velocity, time, dur); + * } + *
+ **/ p5.MonoSynth = function () { AudioVoice.call(this); @@ -76,92 +75,101 @@ define(function (require) { p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype); /** - * Play tells the MonoSynth to start playing a note. This method schedules - * the calling of .triggerAttack and .triggerRelease. - * - * @method play - * @for p5.MonoSynth - * @param {String | Number} note the note you want to play, specified as a - * frequency in Hertz (Number) or as a midi - * value in Note/Octave format ("C4", "Eb3"...etc") - * See - * Tone. Defaults to 440 hz. - * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) - * @param {Number} [secondsFromNow] time from now (in seconds) at which to play - * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds. - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * textAlign(CENTER); - * text('tap to play', width/2, height/2); - * - * monoSynth = new p5.MonoSynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * let note = random(['Fb4', 'G4']); - * // note velocity (volume, from 0 to 1) - * let velocity = random(); - * // time from now (in seconds) - * let time = 0; - * // note duration (in seconds) - * let dur = 1/6; - * - * monoSynth.play(note, velocity, time, dur); - * } - *
- * - */ - p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) { + * Play tells the MonoSynth to start playing a note. This method schedules + * the calling of .triggerAttack and .triggerRelease. + * + * @method play + * @for p5.MonoSynth + * @param {String | Number} note the note you want to play, specified as a + * frequency in Hertz (Number) or as a midi + * value in Note/Octave format ("C4", "Eb3"...etc") + * See + * Tone. Defaults to 440 hz. + * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) + * @param {Number} [secondsFromNow] time from now (in seconds) at which to play + * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds. + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * textAlign(CENTER); + * text('tap to play', width/2, height/2); + * + * monoSynth = new p5.MonoSynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * let note = random(['Fb4', 'G4']); + * // note velocity (volume, from 0 to 1) + * let velocity = random(); + * // time from now (in seconds) + * let time = 0; + * // note duration (in seconds) + * let dur = 1/6; + * + * monoSynth.play(note, velocity, time, dur); + * } + *
+ * + */ + p5.MonoSynth.prototype.play = function ( + note, + velocity, + secondsFromNow, + susTime + ) { this.triggerAttack(note, velocity, ~~secondsFromNow); this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN)); }; /** - * Trigger the Attack, and Decay portion of the Envelope. - * Similar to holding down a key on a piano, but it will - * hold the sustain level until you let go. - * - * @param {String | Number} note the note you want to play, specified as a - * frequency in Hertz (Number) or as a midi - * value in Note/Octave format ("C4", "Eb3"...etc") - * See - * Tone. Defaults to 440 hz - * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) - * @param {Number} [secondsFromNow] time from now (in seconds) at which to play - * @method triggerAttack - * @for p5.MonoSynth - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(triggerAttack); - * background(220); - * text('tap here for attack, let go to release', 5, 20, width - 20); - * monoSynth = new p5.MonoSynth(); - * } - * - * function triggerAttack() { - * userStartAudio(); - * - * monoSynth.triggerAttack("E3"); - * } - * - * function mouseReleased() { - * monoSynth.triggerRelease(); - * } - *
- */ - p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) { + * Trigger the Attack, and Decay portion of the Envelope. + * Similar to holding down a key on a piano, but it will + * hold the sustain level until you let go. + * + * @param {String | Number} note the note you want to play, specified as a + * frequency in Hertz (Number) or as a midi + * value in Note/Octave format ("C4", "Eb3"...etc") + * See + * Tone. Defaults to 440 hz + * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) + * @param {Number} [secondsFromNow] time from now (in seconds) at which to play + * @method triggerAttack + * @for p5.MonoSynth + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(triggerAttack); + * background(220); + * text('tap here for attack, let go to release', 5, 20, width - 20); + * monoSynth = new p5.MonoSynth(); + * } + * + * function triggerAttack() { + * userStartAudio(); + * + * monoSynth.triggerAttack("E3"); + * } + * + * function mouseReleased() { + * monoSynth.triggerRelease(); + * } + *
+ */ + p5.MonoSynth.prototype.triggerAttack = function ( + note, + velocity, + secondsFromNow + ) { var secondsFromNow = ~~secondsFromNow; var freq = noteToFreq(note); var vel = velocity || 0.1; @@ -170,68 +178,67 @@ define(function (require) { }; /** - * Trigger the release of the Envelope. This is similar to releasing - * the key on a piano and letting the sound fade according to the - * release level and release time. - * - * @param {Number} secondsFromNow time to trigger the release - * @method triggerRelease - * @for p5.MonoSynth - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(triggerAttack); - * background(220); - * text('tap here for attack, let go to release', 5, 20, width - 20); - * monoSynth = new p5.MonoSynth(); - * } - * - * function triggerAttack() { - * userStartAudio(); - * - * monoSynth.triggerAttack("E3"); - * } - * - * function mouseReleased() { - * monoSynth.triggerRelease(); - * } - *
- */ + * Trigger the release of the Envelope. This is similar to releasing + * the key on a piano and letting the sound fade according to the + * release level and release time. + * + * @param {Number} secondsFromNow time to trigger the release + * @method triggerRelease + * @for p5.MonoSynth + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(triggerAttack); + * background(220); + * text('tap here for attack, let go to release', 5, 20, width - 20); + * monoSynth = new p5.MonoSynth(); + * } + * + * function triggerAttack() { + * userStartAudio(); + * + * monoSynth.triggerAttack("E3"); + * } + * + * function mouseReleased() { + * monoSynth.triggerRelease(); + * } + *
+ */ p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) { var secondsFromNow = secondsFromNow || 0; this.env.ramp(this.output.gain, secondsFromNow, 0); }; /** - * Set values like a traditional - * - * ADSR envelope - * . - * - * @method setADSR - * @for p5.MonoSynth - * @param {Number} attackTime Time (in seconds before envelope - * reaches Attack Level - * @param {Number} [decayTime] Time (in seconds) before envelope - * reaches Decay/Sustain Level - * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1, - * where 1.0 = attackLevel, 0.0 = releaseLevel. - * The susRatio determines the decayLevel and the level at which the - * sustain portion of the envelope will sustain. - * For example, if attackLevel is 0.4, releaseLevel is 0, - * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is - * increased to 1.0 (using setRange), - * then decayLevel would increase proportionally, to become 0.5. - * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) - */ - p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) { - this.env.setADSR(attack, decay, sustain, release); + * Set values like a traditional + * + * ADSR envelope + * . + * + * @method setADSR + * @for p5.MonoSynth + * @param {Number} attackTime Time (in seconds before envelope + * reaches Attack Level + * @param {Number} [decayTime] Time (in seconds) before envelope + * reaches Decay/Sustain Level + * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1, + * where 1.0 = attackLevel, 0.0 = releaseLevel. + * The susRatio determines the decayLevel and the level at which the + * sustain portion of the envelope will sustain. + * For example, if attackLevel is 0.4, releaseLevel is 0, + * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is + * increased to 1.0 (using setRange), + * then decayLevel would increase proportionally, to become 0.5. + * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) + */ + p5.MonoSynth.prototype.setADSR = function (attack, decay, sustain, release) { + this.env.setADSR(attack, decay, sustain, release); }; - /** * Getters and Setters * @property {Number} attack @@ -250,45 +257,60 @@ define(function (require) { * @for p5.MonoSynth */ Object.defineProperties(p5.MonoSynth.prototype, { - 'attack': { - get : function() { + attack: { + get: function () { return this.env.aTime; }, - set : function(attack) { - this.env.setADSR(attack, this.env.dTime, - this.env.sPercent, this.env.rTime); - } + set: function (attack) { + this.env.setADSR( + attack, + this.env.dTime, + this.env.sPercent, + this.env.rTime + ); + }, }, - 'decay': { - get : function() { + decay: { + get: function () { return this.env.dTime; }, - set : function(decay) { - this.env.setADSR(this.env.aTime, decay, - this.env.sPercent, this.env.rTime); - } + set: function (decay) { + this.env.setADSR( + this.env.aTime, + decay, + this.env.sPercent, + this.env.rTime + ); + }, }, - 'sustain': { - get : function() { + sustain: { + get: function () { return this.env.sPercent; }, - set : function(sustain) { - this.env.setADSR(this.env.aTime, this.env.dTime, - sustain, this.env.rTime); - } + set: function (sustain) { + this.env.setADSR( + this.env.aTime, + this.env.dTime, + sustain, + this.env.rTime + ); + }, }, - 'release': { - get : function() { + release: { + get: function () { return this.env.rTime; }, - set : function(release) { - this.env.setADSR(this.env.aTime, this.env.dTime, - this.env.sPercent, release); - } + set: function (release) { + this.env.setADSR( + this.env.aTime, + this.env.dTime, + this.env.sPercent, + release + ); + }, }, }); - /** * MonoSynth amp * @method amp @@ -297,7 +319,7 @@ define(function (require) { * @param {Number} [rampTime] Time to reach new volume * @return {Number} new volume value */ - p5.MonoSynth.prototype.amp = function(vol, rampTime) { + p5.MonoSynth.prototype.amp = function (vol, rampTime) { var t = rampTime || 0; if (typeof vol !== 'undefined') { this.oscillator.amp(vol, t); @@ -313,7 +335,7 @@ define(function (require) { * @param {Object} unit A p5.sound or Web Audio object */ - p5.MonoSynth.prototype.connect = function(unit) { + p5.MonoSynth.prototype.connect = function (unit) { var u = unit || p5sound.input; this.output.connect(u.input ? u.input : u); }; @@ -324,20 +346,19 @@ define(function (require) { * @method disconnect * @for p5.MonoSynth */ - p5.MonoSynth.prototype.disconnect = function() { + p5.MonoSynth.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } }; - /** * Get rid of the MonoSynth and free up its resources / memory. * * @method dispose * @for p5.MonoSynth */ - p5.MonoSynth.prototype.dispose = function() { + p5.MonoSynth.prototype.dispose = function () { AudioVoice.prototype.dispose.apply(this); if (this.env) { @@ -347,5 +368,4 @@ define(function (require) { this.oscillator.dispose(); } }; - }); diff --git a/src/noise.js b/src/noise.js index b1a6ea77..c0bf00eb 100644 --- a/src/noise.js +++ b/src/noise.js @@ -12,7 +12,7 @@ define(function (require) { * @param {String} type Type of noise can be 'white' (default), * 'brown' or 'pink'. */ - p5.Noise = function(type) { + p5.Noise = function (type) { var assignType; p5.Oscillator.call(this); delete this.f; @@ -32,9 +32,13 @@ define(function (require) { p5.Noise.prototype = Object.create(p5.Oscillator.prototype); // generate noise buffers - var _whiteNoise = (function() { + var _whiteNoise = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; - var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); + var whiteBuffer = p5sound.audiocontext.createBuffer( + 1, + bufferSize, + p5sound.audiocontext.sampleRate + ); var noiseData = whiteBuffer.getChannelData(0); for (var i = 0; i < bufferSize; i++) { noiseData[i] = Math.random() * 2 - 1; @@ -43,9 +47,13 @@ define(function (require) { return whiteBuffer; })(); - var _pinkNoise = (function() { + var _pinkNoise = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; - var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); + var pinkBuffer = p5sound.audiocontext.createBuffer( + 1, + bufferSize, + p5sound.audiocontext.sampleRate + ); var noiseData = pinkBuffer.getChannelData(0); var b0, b1, b2, b3, b4, b5, b6; b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0; @@ -53,10 +61,10 @@ define(function (require) { var white = Math.random() * 2 - 1; b0 = 0.99886 * b0 + white * 0.0555179; b1 = 0.99332 * b1 + white * 0.0750759; - b2 = 0.96900 * b2 + white * 0.1538520; - b3 = 0.86650 * b3 + white * 0.3104856; - b4 = 0.55000 * b4 + white * 0.5329522; - b5 = -0.7616 * b5 - white * 0.0168980; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; noiseData[i] *= 0.11; // (roughly) compensate for gain b6 = white * 0.115926; @@ -65,14 +73,18 @@ define(function (require) { return pinkBuffer; })(); - var _brownNoise = (function() { + var _brownNoise = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; - var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); + var brownBuffer = p5sound.audiocontext.createBuffer( + 1, + bufferSize, + p5sound.audiocontext.sampleRate + ); var noiseData = brownBuffer.getChannelData(0); var lastOut = 0.0; - for (var i = 0; i< bufferSize; i++) { + for (var i = 0; i < bufferSize; i++) { var white = Math.random() * 2 - 1; - noiseData[i] = (lastOut + 0.02*white) / 1.02; + noiseData[i] = (lastOut + 0.02 * white) / 1.02; lastOut = noiseData[i]; noiseData[i] *= 3.5; } @@ -87,8 +99,8 @@ define(function (require) { * @method setType * @param {String} [type] 'white', 'pink' or 'brown' */ - p5.Noise.prototype.setType = function(type) { - switch(type) { + p5.Noise.prototype.setType = function (type) { + switch (type) { case 'white': this.buffer = _whiteNoise; break; @@ -104,15 +116,15 @@ define(function (require) { if (this.started) { var now = p5sound.audiocontext.currentTime; this.stop(now); - this.start(now+.01); + this.start(now + 0.01); } }; - p5.Noise.prototype.getType = function() { + p5.Noise.prototype.getType = function () { return this.buffer.type; }; - p5.Noise.prototype.start = function() { + p5.Noise.prototype.start = function () { if (this.started) { this.stop(); } @@ -125,7 +137,7 @@ define(function (require) { this.started = true; }; - p5.Noise.prototype.stop = function() { + p5.Noise.prototype.stop = function () { var now = p5sound.audiocontext.currentTime; if (this.noise) { this.noise.stop(now); @@ -133,7 +145,7 @@ define(function (require) { } }; - p5.Noise.prototype.dispose = function() { + p5.Noise.prototype.dispose = function () { var now = p5sound.audiocontext.currentTime; // remove reference from soundArray @@ -155,5 +167,4 @@ define(function (require) { this.buffer = null; this.noise = null; }; - }); diff --git a/src/onsetDetect.js b/src/onsetDetect.js index 3da01751..2eb10172 100644 --- a/src/onsetDetect.js +++ b/src/onsetDetect.js @@ -1,7 +1,6 @@ 'use strict'; define(function () { - /** * Listen for onsets (a sharp increase in volume) within a given * frequency range. @@ -13,7 +12,7 @@ define(function () { * @param {Number} threshold Amplitude threshold between 0 (no energy) and 1 (maximum) * @param {Function} callback Function to call when an onset is detected */ - p5.OnsetDetect = function(freqLow, freqHigh, threshold, callback) { + p5.OnsetDetect = function (freqLow, freqHigh, threshold, callback) { this.isDetected = false; this.freqLow = freqLow; this.freqHigh = freqHigh; @@ -28,11 +27,11 @@ define(function () { }; // callback here too? - p5.OnsetDetect.prototype.update = function(fftObject, callback) { - this.energy = fftObject.getEnergy(this.freqLow,this.freqHigh)/255; + p5.OnsetDetect.prototype.update = function (fftObject, callback) { + this.energy = fftObject.getEnergy(this.freqLow, this.freqHigh) / 255; - if(this.isDetected === false) { - if (this.energy-this.penergy > this.treshold) { + if (this.isDetected === false) { + if (this.energy - this.penergy > this.treshold) { this.isDetected = true; if (this.callback) { @@ -44,11 +43,10 @@ define(function () { var self = this; setTimeout(function () { self.isDetected = false; - },this.sensitivity); + }, this.sensitivity); } } this.penergy = this.energy; }; - }); diff --git a/src/oscillator.js b/src/oscillator.js index 798432d9..1d150240 100644 --- a/src/oscillator.js +++ b/src/oscillator.js @@ -69,12 +69,13 @@ define(function (require) { * } * */ - p5.Oscillator = function(freq, type) { + p5.Oscillator = function (freq, type) { if (typeof freq === 'string') { var f = type; type = freq; freq = f; - } if (typeof type === 'number') { + } + if (typeof type === 'number') { var f = type; type = freq; freq = f; @@ -86,7 +87,10 @@ define(function (require) { this.oscillator = p5sound.audiocontext.createOscillator(); this.f = freq || 440.0; // frequency this.oscillator.type = type || 'sine'; - this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime); + this.oscillator.frequency.setValueAtTime( + this.f, + p5sound.audiocontext.currentTime + ); // connections this.output = p5sound.audiocontext.createGain(); @@ -122,7 +126,7 @@ define(function (require) { * @param {Number} [time] startTime in seconds from now. * @param {Number} [frequency] frequency in Hz. */ - p5.Oscillator.prototype.start = function(time, f) { + p5.Oscillator.prototype.start = function (time, f) { if (this.started) { var now = p5sound.audiocontext.currentTime; this.stop(now); @@ -167,7 +171,7 @@ define(function (require) { * @for p5.Oscillator * @param {Number} secondsFromNow Time, in seconds from now. */ - p5.Oscillator.prototype.stop = function(time) { + p5.Oscillator.prototype.stop = function (time) { if (this.started) { var t = time || 0; var now = p5sound.audiocontext.currentTime; @@ -193,16 +197,14 @@ define(function (require) { * this oscillator's * gain/amplitude/volume) */ - p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) { + p5.Oscillator.prototype.amp = function (vol, rampTime, tFromNow) { var self = this; if (typeof vol === 'number') { var rampTime = rampTime || 0; var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); - } - - else if (vol) { + } else if (vol) { vol.connect(self.output.gain); } else { // return the Gain Node @@ -211,9 +213,9 @@ define(function (require) { }; // these are now the same thing - p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp; + p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp; - p5.Oscillator.prototype.getAmp = function() { + p5.Oscillator.prototype.getAmp = function () { return this.output.gain.value; }; @@ -255,7 +257,7 @@ define(function (require) { * } * */ - p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) { + p5.Oscillator.prototype.freq = function (val, rampTime, tFromNow) { if (typeof val === 'number' && !isNaN(val)) { this.f = val; var now = p5sound.audiocontext.currentTime; @@ -268,10 +270,16 @@ define(function (require) { if (rampTime === 0) { this.oscillator.frequency.setValueAtTime(val, tFromNow + now); } else { - if (val > 0 ) { - this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now); + if (val > 0) { + this.oscillator.frequency.exponentialRampToValueAtTime( + val, + tFromNow + rampTime + now + ); } else { - this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now); + this.oscillator.frequency.linearRampToValueAtTime( + val, + tFromNow + rampTime + now + ); } } @@ -279,7 +287,6 @@ define(function (require) { if (this.phaseAmount) { this.phase(this.phaseAmount); } - } else if (val) { if (val.output) { val = val.output; @@ -288,14 +295,14 @@ define(function (require) { // keep track of what is modulating this param // so it can be re-connected if - this._freqMods.push( val ); + this._freqMods.push(val); } else { // return the Frequency Node return this.oscillator.frequency; } }; - p5.Oscillator.prototype.getFreq = function() { + p5.Oscillator.prototype.getFreq = function () { return this.oscillator.frequency.value; }; @@ -306,11 +313,11 @@ define(function (require) { * @for p5.Oscillator * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'. */ - p5.Oscillator.prototype.setType = function(type) { + p5.Oscillator.prototype.setType = function (type) { this.oscillator.type = type; }; - p5.Oscillator.prototype.getType = function() { + p5.Oscillator.prototype.getType = function () { return this.oscillator.type; }; @@ -321,15 +328,13 @@ define(function (require) { * @for p5.Oscillator * @param {Object} unit A p5.sound or Web Audio object */ - p5.Oscillator.prototype.connect = function(unit) { + p5.Oscillator.prototype.connect = function (unit) { if (!unit) { this.panner.connect(p5sound.input); - } - else if (unit.hasOwnProperty('input')) { + } else if (unit.hasOwnProperty('input')) { this.panner.connect(unit.input); this.connection = unit.input; - } - else { + } else { this.panner.connect(unit); this.connection = unit; } @@ -341,7 +346,7 @@ define(function (require) { * @method disconnect * @for p5.Oscillator */ - p5.Oscillator.prototype.disconnect = function() { + p5.Oscillator.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } @@ -363,17 +368,17 @@ define(function (require) { * @param {Number} timeFromNow schedule this event to happen * seconds from now */ - p5.Oscillator.prototype.pan = function(pval, tFromNow) { + p5.Oscillator.prototype.pan = function (pval, tFromNow) { this.panPosition = pval; this.panner.pan(pval, tFromNow); }; - p5.Oscillator.prototype.getPan = function() { + p5.Oscillator.prototype.getPan = function () { return this.panPosition; }; // get rid of the oscillator - p5.Oscillator.prototype.dispose = function() { + p5.Oscillator.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -400,8 +405,8 @@ define(function (require) { * @for p5.Oscillator * @param {Number} phase float between 0.0 and 1.0 */ - p5.Oscillator.prototype.phase = function(p) { - var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f); + p5.Oscillator.prototype.phase = function (p) { + var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1 / this.f); var now = p5sound.audiocontext.currentTime; this.phaseAmount = p; @@ -424,7 +429,7 @@ define(function (require) { // ========================== // // return sigChain(this, scale, thisChain, nextChain, Scale); - var sigChain = function(o, mathObj, thisChain, nextChain, type) { + var sigChain = function (o, mathObj, thisChain, nextChain, type) { var chainSource = o.oscillator; // if this type of math already exists in the chain, replace it for (var i in o.mathOps) { @@ -434,7 +439,7 @@ define(function (require) { thisChain = i; // assume nextChain is output gain node unless... if (thisChain < o.mathOps.length - 2) { - nextChain = o.mathOps[i+1]; + nextChain = o.mathOps[i + 1]; } } } @@ -443,7 +448,7 @@ define(function (require) { } // assume source is the oscillator unless i > 0 if (i > 0) { - chainSource = o.mathOps[i-1]; + chainSource = o.mathOps[i - 1]; } chainSource.disconnect(); chainSource.connect(mathObj); @@ -464,9 +469,9 @@ define(function (require) { * with scaled output * */ - p5.Oscillator.prototype.add = function(num) { + p5.Oscillator.prototype.add = function (num) { var add = new Add(num); - var thisChain = this.mathOps.length-1; + var thisChain = this.mathOps.length - 1; var nextChain = this.output; return sigChain(this, add, thisChain, nextChain, Add); }; @@ -482,9 +487,9 @@ define(function (require) { * @return {p5.Oscillator} Oscillator Returns this oscillator * with multiplied output */ - p5.Oscillator.prototype.mult = function(num) { + p5.Oscillator.prototype.mult = function (num) { var mult = new Mult(num); - var thisChain = this.mathOps.length-1; + var thisChain = this.mathOps.length - 1; var nextChain = this.output; return sigChain(this, mult, thisChain, nextChain, Mult); }; @@ -503,18 +508,17 @@ define(function (require) { * @return {p5.Oscillator} Oscillator Returns this oscillator * with scaled output */ - p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) { + p5.Oscillator.prototype.scale = function (inMin, inMax, outMin, outMax) { var mapOutMin, mapOutMax; if (arguments.length === 4) { mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5; mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5; - } - else { + } else { mapOutMin = arguments[0]; mapOutMax = arguments[1]; } var scale = new Scale(mapOutMin, mapOutMax); - var thisChain = this.mathOps.length-1; + var thisChain = this.mathOps.length - 1; var nextChain = this.output; return sigChain(this, scale, thisChain, nextChain, Scale); @@ -539,7 +543,7 @@ define(function (require) { * @extends p5.Oscillator * @param {Number} [freq] Set the frequency */ - p5.SinOsc = function(freq) { + p5.SinOsc = function (freq) { p5.Oscillator.call(this, freq, 'sine'); }; @@ -558,7 +562,7 @@ define(function (require) { * @extends p5.Oscillator * @param {Number} [freq] Set the frequency */ - p5.TriOsc = function(freq) { + p5.TriOsc = function (freq) { p5.Oscillator.call(this, freq, 'triangle'); }; @@ -577,7 +581,7 @@ define(function (require) { * @extends p5.Oscillator * @param {Number} [freq] Set the frequency */ - p5.SawOsc = function(freq) { + p5.SawOsc = function (freq) { p5.Oscillator.call(this, freq, 'sawtooth'); }; @@ -596,10 +600,9 @@ define(function (require) { * @extends p5.Oscillator * @param {Number} [freq] Set the frequency */ - p5.SqrOsc = function(freq) { + p5.SqrOsc = function (freq) { p5.Oscillator.call(this, freq, 'square'); }; p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype); - }); diff --git a/src/panner.js b/src/panner.js index 1c87ce7f..cab602a1 100644 --- a/src/panner.js +++ b/src/panner.js @@ -1,20 +1,19 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); var ac = p5sound.audiocontext; // Stereo panner // if there is a stereo panner node use it - if(typeof ac.createStereoPanner !== 'undefined') { + if (typeof ac.createStereoPanner !== 'undefined') { p5.Panner = function (input, output) { this.stereoPanner = this.input = ac.createStereoPanner(); input.connect(this.stereoPanner); this.stereoPanner.connect(output); }; - p5.Panner.prototype.pan = function(val, tFromNow) { + p5.Panner.prototype.pan = function (val, tFromNow) { var time = tFromNow || 0; var t = ac.currentTime + time; @@ -25,23 +24,22 @@ define(function (require) { //node does not require this and will automatically //convert single channel or multichannel to stereo. //tested with single and stereo, not with (>2) multichannel - p5.Panner.prototype.inputChannels = function() {}; + p5.Panner.prototype.inputChannels = function () {}; - p5.Panner.prototype.connect = function(obj) { + p5.Panner.prototype.connect = function (obj) { this.stereoPanner.connect(obj); }; - p5.Panner.prototype.disconnect = function() { + p5.Panner.prototype.disconnect = function () { if (this.stereoPanner) { this.stereoPanner.disconnect(); } }; - } else { // if there is no createStereoPanner object // such as in safari 7.1.7 at the time of writing this // use this method to create the effect - p5.Panner = function(input, output, numInputChannels) { + p5.Panner = function (input, output, numInputChannels) { this.input = ac.createGain(); input.connect(this.input); @@ -57,8 +55,7 @@ define(function (require) { this.splitter.connect(this.left, 1); this.splitter.connect(this.right, 0); - } - else { + } else { this.input.connect(this.left); this.input.connect(this.right); } @@ -70,23 +67,23 @@ define(function (require) { }; // -1 is left, +1 is right - p5.Panner.prototype.pan = function(val, tFromNow) { + p5.Panner.prototype.pan = function (val, tFromNow) { var time = tFromNow || 0; var t = ac.currentTime + time; var v = (val + 1) / 2; - var rightVal = Math.cos(v*Math.PI/2); - var leftVal = Math.sin(v * Math.PI/2); + var rightVal = Math.cos((v * Math.PI) / 2); + var leftVal = Math.sin((v * Math.PI) / 2); this.left.gain.linearRampToValueAtTime(leftVal, t); this.right.gain.linearRampToValueAtTime(rightVal, t); }; - p5.Panner.prototype.inputChannels = function(numChannels) { + p5.Panner.prototype.inputChannels = function (numChannels) { if (numChannels === 1) { this.input.disconnect(); this.input.connect(this.left); this.input.connect(this.right); } else if (numChannels === 2) { - if (typeof(this.splitter === 'undefined')) { + if (typeof (this.splitter === 'undefined')) { this.splitter = ac.createChannelSplitter(2); } this.input.disconnect(); @@ -96,11 +93,11 @@ define(function (require) { } }; - p5.Panner.prototype.connect = function(obj) { + p5.Panner.prototype.connect = function (obj) { this.output.connect(obj); }; - p5.Panner.prototype.disconnect = function() { + p5.Panner.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } diff --git a/src/panner3d.js b/src/panner3d.js index ea1b8be1..a424c314 100644 --- a/src/panner3d.js +++ b/src/panner3d.js @@ -1,4 +1,4 @@ -'use strict' +'use strict'; define(function (require) { var p5sound = require('master'); @@ -21,33 +21,32 @@ define(function (require) { * @constructor */ - p5.Panner3D = function() { - Effect.call(this); + p5.Panner3D = function () { + Effect.call(this); - /** - * - * Web Audio Spatial Panner Node - * - * Properties include
- * [Panning Model](https://www.w3.org/TR/webaudio/#idl-def-PanningModelType) - * : "equal power" or "HRTF"
- * [DistanceModel](https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType) - * : "linear", "inverse", or "exponential" - * - * @property {AudioNode} panner - * - */ - this.panner = this.ac.createPanner(); - this.panner.panningModel = 'HRTF'; - this.panner.distanceModel = 'linear'; - this.panner.connect(this.output); - this.input.connect(this.panner); - }; + /** + * + * Web Audio Spatial Panner Node + * + * Properties include
+ * [Panning Model](https://www.w3.org/TR/webaudio/#idl-def-PanningModelType) + * : "equal power" or "HRTF"
+ * [DistanceModel](https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType) + * : "linear", "inverse", or "exponential" + * + * @property {AudioNode} panner + * + */ + this.panner = this.ac.createPanner(); + this.panner.panningModel = 'HRTF'; + this.panner.distanceModel = 'linear'; + this.panner.connect(this.output); + this.input.connect(this.panner); + }; p5.Panner3D.prototype = Object.create(Effect.prototype); - /** * Connect an audio sorce * @@ -55,9 +54,9 @@ define(function (require) { * @for p5.Panner3D * @param {Object} src Input source */ - p5.Panner3D.prototype.process = function(src) { + p5.Panner3D.prototype.process = function (src) { src.connect(this.input); - } + }; /** * Set the X,Y,Z position of the Panner * @method set @@ -68,13 +67,15 @@ define(function (require) { * @param {Number} time * @return {Array} Updated x, y, z values as an array */ - p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) { - this.positionX(xVal,time); - this.positionY(yVal,time); - this.positionZ(zVal,time); - return [this.panner.positionX.value, - this.panner.positionY.value, - this.panner.positionZ.value]; + p5.Panner3D.prototype.set = function (xVal, yVal, zVal, time) { + this.positionX(xVal, time); + this.positionY(yVal, time); + this.positionZ(zVal, time); + return [ + this.panner.positionX.value, + this.panner.positionY.value, + this.panner.positionZ.value, + ]; }; /** @@ -95,34 +96,49 @@ define(function (require) { * @for p5.Panner3D * @return {Number} updated coordinate value */ - p5.Panner3D.prototype.positionX = function(xVal, time) { + p5.Panner3D.prototype.positionX = function (xVal, time) { var t = time || 0; if (typeof xVal === 'number') { this.panner.positionX.value = xVal; - this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t); + this.panner.positionX.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.positionX.linearRampToValueAtTime( + xVal, + this.ac.currentTime + 0.02 + t + ); } else if (xVal) { xVal.connect(this.panner.positionX); } return this.panner.positionX.value; }; - p5.Panner3D.prototype.positionY = function(yVal, time) { + p5.Panner3D.prototype.positionY = function (yVal, time) { var t = time || 0; if (typeof yVal === 'number') { this.panner.positionY.value = yVal; - this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t); + this.panner.positionY.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.positionY.linearRampToValueAtTime( + yVal, + this.ac.currentTime + 0.02 + t + ); } else if (yVal) { yVal.connect(this.panner.positionY); } return this.panner.positionY.value; }; - p5.Panner3D.prototype.positionZ = function(zVal, time) { + p5.Panner3D.prototype.positionZ = function (zVal, time) { var t = time || 0; if (typeof zVal === 'number') { this.panner.positionZ.value = zVal; - this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t); + this.panner.positionZ.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.positionZ.linearRampToValueAtTime( + zVal, + this.ac.currentTime + 0.02 + t + ); } else if (zVal) { zVal.connect(this.panner.positionZ); } @@ -139,13 +155,15 @@ define(function (require) { * @param {Number} time * @return {Array} Updated x, y, z values as an array */ - p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) { - this.orientX(xVal,time); - this.orientY(yVal,time); - this.orientZ(zVal,time); - return [this.panner.orientationX.value, - this.panner.orientationY.value, - this.panner.orientationZ.value]; + p5.Panner3D.prototype.orient = function (xVal, yVal, zVal, time) { + this.orientX(xVal, time); + this.orientY(yVal, time); + this.orientZ(zVal, time); + return [ + this.panner.orientationX.value, + this.panner.orientationY.value, + this.panner.orientationZ.value, + ]; }; /** @@ -166,34 +184,49 @@ define(function (require) { * @for p5.Panner3D * @return {Number} updated coordinate value */ - p5.Panner3D.prototype.orientX = function(xVal, time) { + p5.Panner3D.prototype.orientX = function (xVal, time) { var t = time || 0; if (typeof xVal === 'number') { this.panner.orientationX.value = xVal; - this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t); + this.panner.orientationX.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.orientationX.linearRampToValueAtTime( + xVal, + this.ac.currentTime + 0.02 + t + ); } else if (xVal) { xVal.connect(this.panner.orientationX); } return this.panner.orientationX.value; }; - p5.Panner3D.prototype.orientY = function(yVal, time) { + p5.Panner3D.prototype.orientY = function (yVal, time) { var t = time || 0; if (typeof yVal === 'number') { this.panner.orientationY.value = yVal; - this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t); + this.panner.orientationY.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.orientationY.linearRampToValueAtTime( + yVal, + this.ac.currentTime + 0.02 + t + ); } else if (yVal) { yVal.connect(this.panner.orientationY); } return this.panner.orientationY.value; }; - p5.Panner3D.prototype.orientZ = function(zVal, time) { + p5.Panner3D.prototype.orientZ = function (zVal, time) { var t = time || 0; if (typeof zVal === 'number') { this.panner.orientationZ.value = zVal; - this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t); - this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t); + this.panner.orientationZ.cancelScheduledValues( + this.ac.currentTime + 0.01 + t + ); + this.panner.orientationZ.linearRampToValueAtTime( + zVal, + this.ac.currentTime + 0.02 + t + ); } else if (zVal) { zVal.connect(this.panner.orientationZ); } @@ -207,7 +240,7 @@ define(function (require) { * @param {Number} [maxDistance] * @param {Number} [rolloffFactor] */ - p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) { + p5.Panner3D.prototype.setFalloff = function (maxDistance, rolloffFactor) { this.maxDist(maxDistance); this.rolloff(rolloffFactor); }; @@ -218,7 +251,7 @@ define(function (require) { * @param {Number} maxDistance * @return {Number} updated value */ - p5.Panner3D.prototype.maxDist = function(maxDistance){ + p5.Panner3D.prototype.maxDist = function (maxDistance) { if (typeof maxDistance === 'number') { this.panner.maxDistance = maxDistance; } @@ -232,14 +265,14 @@ define(function (require) { * @param {Number} rolloffFactor * @return {Number} updated value */ - p5.Panner3D.prototype.rolloff = function(rolloffFactor){ + p5.Panner3D.prototype.rolloff = function (rolloffFactor) { if (typeof rolloffFactor === 'number') { this.panner.rolloffFactor = rolloffFactor; } return this.panner.rolloffFactor; }; - p5.Panner3D.dispose = function() { + p5.Panner3D.dispose = function () { Effect.prototype.dispose.apply(this); if (this.panner) { this.panner.disconnect(); @@ -248,5 +281,4 @@ define(function (require) { }; return p5.Panner3D; - }); diff --git a/src/peakDetect.js b/src/peakDetect.js index 271179ad..41c6c48b 100644 --- a/src/peakDetect.js +++ b/src/peakDetect.js @@ -92,7 +92,7 @@ define(function () { * } * */ - p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) { + p5.PeakDetect = function (freq1, freq2, threshold, _framesPerPeak) { // framesPerPeak determines how often to look for a beat. // If a beat is provided, try to look for a beat based on bpm this.framesPerPeak = _framesPerPeak || 20; @@ -124,10 +124,9 @@ define(function () { this.f2 = freq2 || 20000; // function to call when a peak is detected - this._onPeak = function() {}; + this._onPeak = function () {}; }; - /** * The update method is run in the draw loop. * @@ -138,10 +137,9 @@ define(function () { * @method update * @param {p5.FFT} fftObject A p5.FFT object */ - p5.PeakDetect.prototype.update = function(fftObject) { - var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255; - if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) { - + p5.PeakDetect.prototype.update = function (fftObject) { + var nrg = (this.energy = fftObject.getEnergy(this.f1, this.f2) / 255); + if (nrg > this.cutoff && nrg > this.threshold && nrg - this.penergy > 0) { // trigger callback this._onPeak(); this.isDetected = true; @@ -226,12 +224,11 @@ define(function () { * } * */ - p5.PeakDetect.prototype.onPeak = function(callback, val) { + p5.PeakDetect.prototype.onPeak = function (callback, val) { var self = this; - self._onPeak = function() { + self._onPeak = function () { callback(self.energy, val); }; }; - }); diff --git a/src/polysynth.js b/src/polysynth.js index 89fce43e..b7141dc9 100644 --- a/src/polysynth.js +++ b/src/polysynth.js @@ -1,55 +1,54 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); var TimelineSignal = require('Tone/signal/TimelineSignal'); var noteToFreq = require('helpers').noteToFreq; /** - * An AudioVoice is used as a single voice for sound synthesis. - * The PolySynth class holds an array of AudioVoice, and deals - * with voices allocations, with setting notes to be played, and - * parameters to be set. - * - * @class p5.PolySynth - * @constructor - * - * @param {Number} [synthVoice] A monophonic synth voice inheriting - * the AudioVoice class. Defaults to p5.MonoSynth - * @param {Number} [maxVoices] Number of voices, defaults to 8; - * @example - *
- * let polySynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * text('click to play', 20, 20); - * - * polySynth = new p5.PolySynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * // note duration (in seconds) - * let dur = 1.5; - * - * // time from now (in seconds) - * let time = 0; - * - * // velocity (volume, from 0 to 1) - * let vel = 0.1; - * - * // notes can overlap with each other - * polySynth.play('G2', vel, 0, dur); - * polySynth.play('C3', vel, time += 1/3, dur); - * polySynth.play('G3', vel, time += 1/3, dur); - * } - *
- **/ - p5.PolySynth = function(audioVoice, maxVoices) { + * An AudioVoice is used as a single voice for sound synthesis. + * The PolySynth class holds an array of AudioVoice, and deals + * with voices allocations, with setting notes to be played, and + * parameters to be set. + * + * @class p5.PolySynth + * @constructor + * + * @param {Number} [synthVoice] A monophonic synth voice inheriting + * the AudioVoice class. Defaults to p5.MonoSynth + * @param {Number} [maxVoices] Number of voices, defaults to 8; + * @example + *
+ * let polySynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * text('click to play', 20, 20); + * + * polySynth = new p5.PolySynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * // note duration (in seconds) + * let dur = 1.5; + * + * // time from now (in seconds) + * let time = 0; + * + * // velocity (volume, from 0 to 1) + * let vel = 0.1; + * + * // notes can overlap with each other + * polySynth.play('G2', vel, 0, dur); + * polySynth.play('C3', vel, time += 1/3, dur); + * polySynth.play('G3', vel, time += 1/3, dur); + * } + *
+ **/ + p5.PolySynth = function (audioVoice, maxVoices) { //audiovoices will contain maxVoices many monophonic synths this.audiovoices = []; @@ -83,7 +82,7 @@ define(function (require) { /** * This value must only change as a note is attacked or released. Due to delay * and sustain times, Tone.TimelineSignal is required to schedule the change in value. - * @private + * @private * @property {Tone.TimelineSignal} _voicesInUse */ this._voicesInUse = new TimelineSignal(0); @@ -102,8 +101,8 @@ define(function (require) { * @for p5.PolySynth * @method _allocateVoices */ - p5.PolySynth.prototype._allocateVoices = function() { - for(var i = 0; i< this.maxVoices; i++) { + p5.PolySynth.prototype._allocateVoices = function () { + for (var i = 0; i < this.maxVoices; i++) { this.audiovoices.push(new this.AudioVoice()); this.audiovoices[i].disconnect(); this.audiovoices[i].connect(this.output); @@ -151,13 +150,17 @@ define(function (require) { * } * */ - p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) { + p5.PolySynth.prototype.play = function ( + note, + velocity, + secondsFromNow, + susTime + ) { var susTime = susTime || 1; this.noteAttack(note, velocity, secondsFromNow); this.noteRelease(note, secondsFromNow + susTime); }; - /** * noteADSR sets the envelope for a specific note that has just been triggered. * Using this method modifies the envelope of whichever audiovoice is being used @@ -182,14 +185,13 @@ define(function (require) { * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) **/ - p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) { + p5.PolySynth.prototype.noteADSR = function (note, a, d, s, r, timeFromNow) { var now = p5sound.audiocontext.currentTime; var timeFromNow = timeFromNow || 0; - var t = now + timeFromNow - this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r); + var t = now + timeFromNow; + this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r); }; - /** * Set the PolySynths global envelope. This method modifies the envelopes of each * monosynth so that all notes are played with this envelope. @@ -210,9 +212,9 @@ define(function (require) { * then decayLevel would increase proportionally, to become 0.5. * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) **/ - p5.PolySynth.prototype.setADSR = function(a,d,s,r) { - this.audiovoices.forEach(function(voice) { - voice.setADSR(a,d,s,r); + p5.PolySynth.prototype.setADSR = function (a, d, s, r) { + this.audiovoices.forEach(function (voice) { + voice.setADSR(a, d, s, r); }); }; @@ -255,7 +257,11 @@ define(function (require) { * } * */ - p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) { + p5.PolySynth.prototype.noteAttack = function ( + _note, + _velocity, + secondsFromNow + ) { //this value goes to the audiovoices which handle their own scheduling var secondsFromNow = ~~secondsFromNow; @@ -283,9 +289,11 @@ define(function (require) { else { currentVoice = this._oldest; - var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value); + var oldestNote = p5.prototype.freqToMidi( + this.audiovoices[this._oldest].oscillator.freq().value + ); this.noteRelease(oldestNote); - this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1); + this._oldest = (this._oldest + 1) % (this.maxVoices - 1); } //Overrite the entry in the notes object. A note (frequency value) @@ -295,7 +303,10 @@ define(function (require) { //Find the scheduled change in this._voicesInUse that will be previous to this new note //Add 1 and schedule this value at time 't', when this note will start playing - var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value; + var previousVal = + this._voicesInUse._searchBefore(acTime) === null + ? 0 + : this._voicesInUse._searchBefore(acTime).value; this._voicesInUse.setValueAtTime(previousVal + 1, acTime); //Then update all scheduled values that follow to increase by 1 @@ -304,10 +315,14 @@ define(function (require) { this._newest = currentVoice; //The audiovoice handles the actual scheduling of the note if (typeof velocity === 'number') { - var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2; + var maxRange = (1 / this._voicesInUse.getValueAtTime(acTime)) * 2; velocity = velocity > maxRange ? maxRange : velocity; } - this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow); + this.audiovoices[currentVoice].triggerAttack( + note, + velocity, + secondsFromNow + ); }; /** @@ -322,17 +337,16 @@ define(function (require) { * @param {[type]} value [description] * @return {[type]} [description] */ - p5.PolySynth.prototype._updateAfter = function(time, value) { - if(this._voicesInUse._searchAfter(time) === null) { + p5.PolySynth.prototype._updateAfter = function (time, value) { + if (this._voicesInUse._searchAfter(time) === null) { return; - } else{ + } else { this._voicesInUse._searchAfter(time).value += value; var nextTime = this._voicesInUse._searchAfter(time).time; this._updateAfter(nextTime, value); } }; - /** * Trigger the Release of an AudioVoice note. This is similar to releasing * the key on a piano and letting the sound fade according to the @@ -373,15 +387,15 @@ define(function (require) { * * */ - p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) { - var now = p5sound.audiocontext.currentTime; + p5.PolySynth.prototype.noteRelease = function (_note, secondsFromNow) { + var now = p5sound.audiocontext.currentTime; var tFromNow = secondsFromNow || 0; var t = now + tFromNow; // if a note value is not provided, release all voices if (!_note) { - this.audiovoices.forEach(function(voice) { - voice.triggerRelease(tFromNow) + this.audiovoices.forEach(function (voice) { + voice.triggerRelease(tFromNow); }); this._voicesInUse.setValueAtTime(0, t); for (var n in this.notes) { @@ -399,54 +413,59 @@ define(function (require) { } else { //Find the scheduled change in this._voicesInUse that will be previous to this new note //subtract 1 and schedule this value at time 't', when this note will stop playing - var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1); + var previousVal = Math.max( + ~~this._voicesInUse.getValueAtTime(t).value, + 1 + ); this._voicesInUse.setValueAtTime(previousVal - 1, t); //Then update all scheduled values that follow to decrease by 1 but never go below 0 if (previousVal > 0) { this._updateAfter(t, -1); } - this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow); + this.audiovoices[this.notes[note].getValueAtTime(t)].triggerRelease( + tFromNow + ); this.notes[note].dispose(); delete this.notes[note]; - this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1); + this._newest = + this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1); } - }; /** - * Connect to a p5.sound / Web Audio object. - * - * @method connect - * @for p5.PolySynth - * @param {Object} unit A p5.sound or Web Audio object - */ + * Connect to a p5.sound / Web Audio object. + * + * @method connect + * @for p5.PolySynth + * @param {Object} unit A p5.sound or Web Audio object + */ p5.PolySynth.prototype.connect = function (unit) { var u = unit || p5sound.input; this.output.connect(u.input ? u.input : u); }; /** - * Disconnect all outputs - * - * @method disconnect - * @for p5.PolySynth - */ - p5.PolySynth.prototype.disconnect = function() { + * Disconnect all outputs + * + * @method disconnect + * @for p5.PolySynth + */ + p5.PolySynth.prototype.disconnect = function () { if (this.output) { this.output.disconnect(); } }; /** - * Get rid of the MonoSynth and free up its resources / memory. - * - * @method dispose - * @for p5.PolySynth - */ - p5.PolySynth.prototype.dispose = function() { - this.audiovoices.forEach(function(voice) { + * Get rid of the MonoSynth and free up its resources / memory. + * + * @method dispose + * @for p5.PolySynth + */ + p5.PolySynth.prototype.dispose = function () { + this.audiovoices.forEach(function (voice) { voice.dispose(); }); @@ -455,5 +474,4 @@ define(function (require) { delete this.output; } }; - }); diff --git a/src/pulse.js b/src/pulse.js index 48608ba4..bbfecd81 100644 --- a/src/pulse.js +++ b/src/pulse.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); require('oscillator'); @@ -49,7 +48,7 @@ define(function (require) { * } * */ - p5.Pulse = function(freq, w) { + p5.Pulse = function (freq, w) { p5.Oscillator.call(this, freq, 'sawtooth'); // width of PWM, should be betw 0 to 1.0 @@ -70,7 +69,7 @@ define(function (require) { this.f = freq || 440; var mW = this.w / this.oscillator.frequency.value; this.dNode.delayTime.value = mW; - this.dcGain.gain.value = 1.7*(0.5-this.w); + this.dcGain.gain.value = 1.7 * (0.5 - this.w); // disconnect osc2 and connect it to delay, which is connected to output this.osc2.disconnect(); @@ -93,7 +92,7 @@ define(function (require) { * @param {Number} [width] Width between the pulses (0 to 1.0, * defaults to 0) */ - p5.Pulse.prototype.width = function(w) { + p5.Pulse.prototype.width = function (w) { if (typeof w === 'number') { if (w <= 1.0 && w >= 0.0) { this.w = w; @@ -104,7 +103,7 @@ define(function (require) { this.dNode.delayTime.value = mW; } - this.dcGain.gain.value = 1.7*(0.5-this.w); + this.dcGain.gain.value = 1.7 * (0.5 - this.w); } else { w.connect(this.dNode.delayTime); var sig = new p5.SignalAdd(-0.5); @@ -115,7 +114,7 @@ define(function (require) { } }; - p5.Pulse.prototype.start = function(f, time) { + p5.Pulse.prototype.start = function (f, time) { var now = p5sound.audiocontext.currentTime; var t = time || 0; if (!this.started) { @@ -133,7 +132,10 @@ define(function (require) { this.osc2.oscillator.type = type; this.osc2.oscillator.connect(this.osc2.output); this.osc2.start(t + now); - this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency]; + this.freqNode = [ + this.oscillator.frequency, + this.osc2.oscillator.frequency, + ]; // start dcOffset, too this.dcOffset = createDCOffset(); @@ -150,7 +152,7 @@ define(function (require) { } }; - p5.Pulse.prototype.stop = function(time) { + p5.Pulse.prototype.stop = function (time) { if (this.started) { var t = time || 0; var now = p5sound.audiocontext.currentTime; @@ -164,7 +166,7 @@ define(function (require) { } }; - p5.Pulse.prototype.freq = function(val, rampTime, tFromNow) { + p5.Pulse.prototype.freq = function (val, rampTime, tFromNow) { if (typeof val === 'number') { this.f = val; var now = p5sound.audiocontext.currentTime; @@ -173,16 +175,24 @@ define(function (require) { var currentFreq = this.oscillator.frequency.value; this.oscillator.frequency.cancelScheduledValues(now); this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow); - this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now); + this.oscillator.frequency.exponentialRampToValueAtTime( + val, + tFromNow + rampTime + now + ); this.osc2.oscillator.frequency.cancelScheduledValues(now); - this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow); - this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now); + this.osc2.oscillator.frequency.setValueAtTime( + currentFreq, + now + tFromNow + ); + this.osc2.oscillator.frequency.exponentialRampToValueAtTime( + val, + tFromNow + rampTime + now + ); if (this.freqMod) { this.freqMod.output.disconnect(); this.freqMod = null; } - } else if (val.output) { val.output.disconnect(); val.output.connect(this.oscillator.frequency); @@ -194,14 +204,12 @@ define(function (require) { // inspiration: http://webaudiodemos.appspot.com/oscilloscope/ function createDCOffset() { var ac = p5sound.audiocontext; - var buffer=ac.createBuffer(1,2048,ac.sampleRate); + var buffer = ac.createBuffer(1, 2048, ac.sampleRate); var data = buffer.getChannelData(0); - for (var i=0; i<2048; i++) - data[i]=1.0; - var bufferSource=ac.createBufferSource(); - bufferSource.buffer=buffer; - bufferSource.loop=true; + for (var i = 0; i < 2048; i++) data[i] = 1.0; + var bufferSource = ac.createBufferSource(); + bufferSource.buffer = buffer; + bufferSource.loop = true; return bufferSource; } - }); diff --git a/src/reverb.js b/src/reverb.js index aedad3be..22dd759c 100644 --- a/src/reverb.js +++ b/src/reverb.js @@ -56,8 +56,7 @@ define(function (require) { * */ - - p5.Reverb = function() { + p5.Reverb = function () { Effect.call(this); this._initConvolverNode(); @@ -71,25 +70,24 @@ define(function (require) { this._reverse = false; this._buildImpulse(); - }; p5.Reverb.prototype = Object.create(Effect.prototype); - p5.Reverb.prototype._initConvolverNode = function() { + p5.Reverb.prototype._initConvolverNode = function () { this.convolverNode = this.ac.createConvolver(); this.input.connect(this.convolverNode); this.convolverNode.connect(this.wet); }; - p5.Reverb.prototype._teardownConvolverNode = function() { + p5.Reverb.prototype._teardownConvolverNode = function () { if (this.convolverNode) { this.convolverNode.disconnect(); delete this.convolverNode; } }; - p5.Reverb.prototype._setBuffer = function(audioBuffer) { + p5.Reverb.prototype._setBuffer = function (audioBuffer) { this._teardownConvolverNode(); this._initConvolverNode(); this.convolverNode.buffer = audioBuffer; @@ -107,7 +105,7 @@ define(function (require) { * Min: 0, Max: 100. Defaults to 2. * @param {Boolean} [reverse] Play the reverb backwards or forwards. */ - p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) { + p5.Reverb.prototype.process = function (src, seconds, decayRate, reverse) { src.connect(this.input); var rebuild = false; if (seconds) { @@ -137,7 +135,7 @@ define(function (require) { * Min: 0, Max: 100. Defaults to 2. * @param {Boolean} [reverse] Play the reverb backwards or forwards. */ - p5.Reverb.prototype.set = function(seconds, decayRate, reverse) { + p5.Reverb.prototype.set = function (seconds, decayRate, reverse) { var rebuild = false; if (seconds) { this._seconds = seconds; @@ -188,9 +186,9 @@ define(function (require) { * * @private */ - p5.Reverb.prototype._buildImpulse = function() { + p5.Reverb.prototype._buildImpulse = function () { var rate = this.ac.sampleRate; - var length = rate*this._seconds; + var length = rate * this._seconds; var decay = this._decay; var impulse = this.ac.createBuffer(2, length, rate); var impulseL = impulse.getChannelData(0); @@ -204,7 +202,7 @@ define(function (require) { this._setBuffer(impulse); }; - p5.Reverb.prototype.dispose = function() { + p5.Reverb.prototype.dispose = function () { Effect.prototype.dispose.apply(this); this._teardownConvolverNode(); }; @@ -273,8 +271,8 @@ define(function (require) { * } * */ - p5.Convolver = function(path, callback, errorCallback) { - p5.Reverb.call(this); + p5.Convolver = function (path, callback, errorCallback) { + p5.Reverb.call(this); /** * Internally, the p5.Convolver uses the a @@ -291,8 +289,7 @@ define(function (require) { if (path) { this.impulses = []; this._loadBuffer(path, callback, errorCallback); - } - else { + } else { // parameters this._seconds = 3; this._decay = 2; @@ -300,7 +297,6 @@ define(function (require) { this._buildImpulse(); } - }; p5.Convolver.prototype = Object.create(p5.Reverb.prototype); @@ -356,21 +352,30 @@ define(function (require) { * } * */ - p5.prototype.createConvolver = function(path, callback, errorCallback) { + p5.prototype.createConvolver = function (path, callback, errorCallback) { // if loading locally without a server - if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { - alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); + if ( + window.location.origin.indexOf('file://') > -1 && + window.cordova === 'undefined' + ) { + alert( + 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS' + ); } var self = this; - var cReverb = new p5.Convolver(path, function(buffer) { - if (typeof callback === 'function') { - callback(buffer); - } + var cReverb = new p5.Convolver( + path, + function (buffer) { + if (typeof callback === 'function') { + callback(buffer); + } - if (typeof self._decrementPreload === 'function') { - self._decrementPreload(); - } - }, errorCallback); + if (typeof self._decrementPreload === 'function') { + self._decrementPreload(); + } + }, + errorCallback + ); cReverb.impulses = []; return cReverb; }; @@ -384,7 +389,11 @@ define(function (require) { * @param {Function} errorCallback * @private */ - p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) { + p5.Convolver.prototype._loadBuffer = function ( + path, + callback, + errorCallback + ) { var path = p5.prototype._checkFileFormats(path); var self = this; var errorTrace = new Error().stack; @@ -394,11 +403,12 @@ define(function (require) { request.open('GET', path, true); request.responseType = 'arraybuffer'; - request.onload = function() { + request.onload = function () { if (request.status === 200) { // on success loading file: - ac.decodeAudioData(request.response, - function(buff) { + ac.decodeAudioData( + request.response, + function (buff) { var buffer = {}; var chunks = path.split('/'); buffer.name = chunks[chunks.length - 1]; @@ -410,14 +420,16 @@ define(function (require) { } }, // error decoding buffer. "e" is undefined in Chrome 11/22/2015 - function() { + function () { var err = new CustomError('decodeAudioData', errorTrace, self.url); var msg = 'AudioContext error at decodeAudioData for ' + self.url; if (errorCallback) { err.msg = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } } ); @@ -425,28 +437,41 @@ define(function (require) { // if request status != 200, it failed else { var err = new CustomError('loadConvolver', errorTrace, self.url); - var msg = 'Unable to load ' + self.url + - '. The request status was: ' + request.status + ' (' + request.statusText + ')'; + var msg = + 'Unable to load ' + + self.url + + '. The request status was: ' + + request.status + + ' (' + + request.statusText + + ')'; if (errorCallback) { err.message = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } } }; // if there is another error, aside from 404... - request.onerror = function() { + request.onerror = function () { var err = new CustomError('loadConvolver', errorTrace, self.url); - var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.'; + var msg = + 'There was no response from the server at ' + + self.url + + '. Check the url and internet connectivity.'; if (errorCallback) { err.message = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } }; request.send(); @@ -497,7 +522,7 @@ define(function (require) { * * */ - p5.Convolver.prototype.process = function(src) { + p5.Convolver.prototype.process = function (src) { src.connect(this.input); }; @@ -523,10 +548,15 @@ define(function (require) { * @param {Function} callback function (optional) * @param {Function} errorCallback function (optional) */ - p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) { + p5.Convolver.prototype.addImpulse = function (path, callback, errorCallback) { // if loading locally without a server - if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { - alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); + if ( + window.location.origin.indexOf('file://') > -1 && + window.cordova === 'undefined' + ) { + alert( + 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS' + ); } this._loadBuffer(path, callback, errorCallback); }; @@ -542,10 +572,19 @@ define(function (require) { * @param {Function} callback function (optional) * @param {Function} errorCallback function (optional) */ - p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) { + p5.Convolver.prototype.resetImpulse = function ( + path, + callback, + errorCallback + ) { // if loading locally without a server - if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { - alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); + if ( + window.location.origin.indexOf('file://') > -1 && + window.cordova === 'undefined' + ) { + alert( + 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS' + ); } this.impulses = []; this._loadBuffer(path, callback, errorCallback); @@ -571,7 +610,7 @@ define(function (require) { * (String), or by its position in the * .impulses Array (Number). */ - p5.Convolver.prototype.toggleImpulse = function(id) { + p5.Convolver.prototype.toggleImpulse = function (id) { if (typeof id === 'number' && id < this.impulses.length) { this._setBuffer(this.impulses[id].audioBuffer); } @@ -585,7 +624,7 @@ define(function (require) { } }; - p5.Convolver.prototype.dispose = function() { + p5.Convolver.prototype.dispose = function () { p5.Reverb.prototype.dispose.apply(this); // remove all the Impulse Response buffers @@ -595,5 +634,4 @@ define(function (require) { } } }; - }); diff --git a/src/shims.js b/src/shims.js index 3de3f62f..2d7bc44d 100644 --- a/src/shims.js +++ b/src/shims.js @@ -5,7 +5,6 @@ */ define(function () { - /* AudioContext Monkeypatch Copyright 2013 Chris Wilson Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,75 +19,85 @@ define(function () { */ (function () { function fixSetTarget(param) { - if (!param) // if NYI, just return + if (!param) + // if NYI, just return return; if (!param.setTargetAtTime) param.setTargetAtTime = param.setTargetValueAtTime; } - if (window.hasOwnProperty('webkitAudioContext') && - !window.hasOwnProperty('AudioContext')) { + if ( + window.hasOwnProperty('webkitAudioContext') && + !window.hasOwnProperty('AudioContext') + ) { window.AudioContext = window.webkitAudioContext; if (typeof AudioContext.prototype.createGain !== 'function') - AudioContext.prototype.createGain = AudioContext.prototype.createGainNode; + AudioContext.prototype.createGain = + AudioContext.prototype.createGainNode; if (typeof AudioContext.prototype.createDelay !== 'function') - AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode; + AudioContext.prototype.createDelay = + AudioContext.prototype.createDelayNode; if (typeof AudioContext.prototype.createScriptProcessor !== 'function') - AudioContext.prototype.createScriptProcessor = AudioContext.prototype.createJavaScriptNode; + AudioContext.prototype.createScriptProcessor = + AudioContext.prototype.createJavaScriptNode; if (typeof AudioContext.prototype.createPeriodicWave !== 'function') - AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable; - + AudioContext.prototype.createPeriodicWave = + AudioContext.prototype.createWaveTable; - AudioContext.prototype.internal_createGain = AudioContext.prototype.createGain; - AudioContext.prototype.createGain = function() { + AudioContext.prototype.internal_createGain = + AudioContext.prototype.createGain; + AudioContext.prototype.createGain = function () { var node = this.internal_createGain(); fixSetTarget(node.gain); return node; }; - AudioContext.prototype.internal_createDelay = AudioContext.prototype.createDelay; - AudioContext.prototype.createDelay = function(maxDelayTime) { - var node = maxDelayTime ? this.internal_createDelay(maxDelayTime) : this.internal_createDelay(); + AudioContext.prototype.internal_createDelay = + AudioContext.prototype.createDelay; + AudioContext.prototype.createDelay = function (maxDelayTime) { + var node = maxDelayTime + ? this.internal_createDelay(maxDelayTime) + : this.internal_createDelay(); fixSetTarget(node.delayTime); return node; }; - AudioContext.prototype.internal_createBufferSource = AudioContext.prototype.createBufferSource; - AudioContext.prototype.createBufferSource = function() { + AudioContext.prototype.internal_createBufferSource = + AudioContext.prototype.createBufferSource; + AudioContext.prototype.createBufferSource = function () { var node = this.internal_createBufferSource(); if (!node.start) { - node.start = function ( when, offset, duration ) { - if ( offset || duration ) - this.noteGrainOn( when || 0, offset, duration ); - else - this.noteOn( when || 0 ); + node.start = function (when, offset, duration) { + if (offset || duration) + this.noteGrainOn(when || 0, offset, duration); + else this.noteOn(when || 0); }; } else { node.internal_start = node.start; - node.start = function( when, offset, duration ) { - if( typeof duration !== 'undefined' ) - node.internal_start( when || 0, offset, duration ); - else - node.internal_start( when || 0, offset || 0 ); + node.start = function (when, offset, duration) { + if (typeof duration !== 'undefined') + node.internal_start(when || 0, offset, duration); + else node.internal_start(when || 0, offset || 0); }; } if (!node.stop) { - node.stop = function ( when ) { - this.noteOff( when || 0 ); + node.stop = function (when) { + this.noteOff(when || 0); }; } else { node.internal_stop = node.stop; - node.stop = function( when ) { - node.internal_stop( when || 0 ); + node.stop = function (when) { + node.internal_stop(when || 0); }; } fixSetTarget(node.playbackRate); return node; }; - AudioContext.prototype.internal_createDynamicsCompressor = AudioContext.prototype.createDynamicsCompressor; - AudioContext.prototype.createDynamicsCompressor = function() { + AudioContext.prototype.internal_createDynamicsCompressor = + AudioContext.prototype.createDynamicsCompressor; + AudioContext.prototype.createDynamicsCompressor = function () { var node = this.internal_createDynamicsCompressor(); fixSetTarget(node.threshold); fixSetTarget(node.knee); @@ -99,8 +108,9 @@ define(function () { return node; }; - AudioContext.prototype.internal_createBiquadFilter = AudioContext.prototype.createBiquadFilter; - AudioContext.prototype.createBiquadFilter = function() { + AudioContext.prototype.internal_createBiquadFilter = + AudioContext.prototype.createBiquadFilter; + AudioContext.prototype.createBiquadFilter = function () { var node = this.internal_createBiquadFilter(); fixSetTarget(node.frequency); fixSetTarget(node.detune); @@ -110,31 +120,31 @@ define(function () { }; if (typeof AudioContext.prototype.createOscillator !== 'function') { - AudioContext.prototype.internal_createOscillator = AudioContext.prototype.createOscillator; - AudioContext.prototype.createOscillator = function() { + AudioContext.prototype.internal_createOscillator = + AudioContext.prototype.createOscillator; + AudioContext.prototype.createOscillator = function () { var node = this.internal_createOscillator(); if (!node.start) { - node.start = function ( when ) { - this.noteOn( when || 0 ); + node.start = function (when) { + this.noteOn(when || 0); }; } else { node.internal_start = node.start; - node.start = function ( when ) { - node.internal_start( when || 0); + node.start = function (when) { + node.internal_start(when || 0); }; } if (!node.stop) { - node.stop = function ( when ) { - this.noteOff( when || 0 ); + node.stop = function (when) { + this.noteOff(when || 0); }; } else { node.internal_stop = node.stop; - node.stop = function( when ) { - node.internal_stop( when || 0 ); + node.stop = function (when) { + node.internal_stop(when || 0); }; } - if (!node.setPeriodicWave) - node.setPeriodicWave = node.setWaveTable; + if (!node.setPeriodicWave) node.setPeriodicWave = node.setWaveTable; fixSetTarget(node.frequency); fixSetTarget(node.detune); return node; @@ -142,48 +152,51 @@ define(function () { } } - if (window.hasOwnProperty('webkitOfflineAudioContext') && - !window.hasOwnProperty('OfflineAudioContext')) { + if ( + window.hasOwnProperty('webkitOfflineAudioContext') && + !window.hasOwnProperty('OfflineAudioContext') + ) { window.OfflineAudioContext = window.webkitOfflineAudioContext; } - })(window); // <-- end MonkeyPatch. // Polyfill for AudioIn, also handled by p5.dom createCapture - navigator.getUserMedia = navigator.getUserMedia || + navigator.getUserMedia = + navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; - /** * Determine which filetypes are supported (inspired by buzz.js) * The audio element (el) will only be used to test browser support for various audio formats */ var el = document.createElement('audio'); - p5.prototype.isSupported = function() { + p5.prototype.isSupported = function () { return !!el.canPlayType; }; - var isOGGSupported = function() { + var isOGGSupported = function () { return !!el.canPlayType && el.canPlayType('audio/ogg; codecs="vorbis"'); }; - var isMP3Supported = function() { + var isMP3Supported = function () { return !!el.canPlayType && el.canPlayType('audio/mpeg;'); }; - var isWAVSupported = function() { + var isWAVSupported = function () { return !!el.canPlayType && el.canPlayType('audio/wav; codecs="1"'); }; - var isAACSupported = function() { - return !!el.canPlayType && (el.canPlayType('audio/x-m4a;') || el.canPlayType('audio/aac;')); + var isAACSupported = function () { + return ( + !!el.canPlayType && + (el.canPlayType('audio/x-m4a;') || el.canPlayType('audio/aac;')) + ); }; - var isAIFSupported = function() { + var isAIFSupported = function () { return !!el.canPlayType && el.canPlayType('audio/x-aiff;'); }; - p5.prototype.isFileSupported = function(extension) { - switch(extension.toLowerCase()) - { + p5.prototype.isFileSupported = function (extension) { + switch (extension.toLowerCase()) { case 'mp3': return isMP3Supported(); case 'wav': diff --git a/src/signal.js b/src/signal.js index 4c48bbc5..eda7115c 100644 --- a/src/signal.js +++ b/src/signal.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - // Signal is built with the Tone.js signal by Yotam Mann // https://github.com/TONEnoTONE/Tone.js/ var Signal = require('Tone/signal/Signal'); @@ -69,7 +68,7 @@ define(function (require) { * } * */ - p5.Signal = function(value) { + p5.Signal = function (value) { var s = new Signal(value); // p5sound.soundArray.push(s); return s; // TODO: is this really a constructor? @@ -84,10 +83,9 @@ define(function (require) { * @param {Number} [secondsFromNow] Length of fade, in seconds from now */ Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime; - Mult.prototype.fade = Signal.prototype.fade; - Add.prototype.fade = Signal.prototype.fade; - Scale.prototype.fade = Signal.prototype.fade; - + Mult.prototype.fade = Signal.prototype.fade; + Add.prototype.fade = Signal.prototype.fade; + Scale.prototype.fade = Signal.prototype.fade; /** * Connect a p5.sound object or Web Audio node to this @@ -97,13 +95,12 @@ define(function (require) { * @for p5.Signal * @param {Object} input */ - Signal.prototype.setInput = function(_input) { + Signal.prototype.setInput = function (_input) { _input.connect(this); }; - Mult.prototype.setInput = Signal.prototype.setInput; - Add.prototype.setInput = Signal.prototype.setInput; - Scale.prototype.setInput = Signal.prototype.setInput; - + Mult.prototype.setInput = Signal.prototype.setInput; + Add.prototype.setInput = Signal.prototype.setInput; + Scale.prototype.setInput = Signal.prototype.setInput; // signals can add / mult / scale themselves @@ -118,15 +115,15 @@ define(function (require) { * @param {Number} number * @return {p5.Signal} object */ - Signal.prototype.add = function(num) { + Signal.prototype.add = function (num) { var add = new Add(num); // add.setInput(this); this.connect(add); return add; }; - Mult.prototype.add = Signal.prototype.add; - Add.prototype.add = Signal.prototype.add; - Scale.prototype.add = Signal.prototype.add; + Mult.prototype.add = Signal.prototype.add; + Add.prototype.add = Signal.prototype.add; + Scale.prototype.add = Signal.prototype.add; /** * Multiply this signal by a constant value, @@ -139,15 +136,15 @@ define(function (require) { * @param {Number} number to multiply * @return {p5.Signal} object */ - Signal.prototype.mult = function(num) { + Signal.prototype.mult = function (num) { var mult = new Mult(num); // mult.setInput(this); this.connect(mult); return mult; }; - Mult.prototype.mult = Signal.prototype.mult; - Add.prototype.mult = Signal.prototype.mult; - Scale.prototype.mult = Signal.prototype.mult; + Mult.prototype.mult = Signal.prototype.mult; + Add.prototype.mult = Signal.prototype.mult; + Scale.prototype.mult = Signal.prototype.mult; /** * Scale this signal value to a given range, @@ -164,13 +161,12 @@ define(function (require) { * @param {Number} outMax input range maximum * @return {p5.Signal} object */ - Signal.prototype.scale = function(inMin, inMax, outMin, outMax) { + Signal.prototype.scale = function (inMin, inMax, outMin, outMax) { var mapOutMin, mapOutMax; if (arguments.length === 4) { mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5; mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5; - } - else { + } else { mapOutMin = arguments[0]; mapOutMax = arguments[1]; } @@ -178,10 +174,7 @@ define(function (require) { this.connect(scale); return scale; }; - Mult.prototype.scale = Signal.prototype.scale; - Add.prototype.scale = Signal.prototype.scale; - Scale.prototype.scale = Signal.prototype.scale; - + Mult.prototype.scale = Signal.prototype.scale; + Add.prototype.scale = Signal.prototype.scale; + Scale.prototype.scale = Signal.prototype.scale; }); - - diff --git a/src/soundLoop.js b/src/soundLoop.js index dd15d476..4375dfba 100644 --- a/src/soundLoop.js +++ b/src/soundLoop.js @@ -54,7 +54,7 @@ define(function (require) { * } * */ - p5.SoundLoop = function(callback, interval) { + p5.SoundLoop = function (callback, interval) { this.callback = callback; /** * musicalTimeMode uses Tone.Time convention @@ -82,7 +82,7 @@ define(function (require) { var self = this; this.clock = new Clock({ - 'callback' : function(time) { + callback: function (time) { var timeFromNow = time - p5sound.audiocontext.currentTime; /** * Do not initiate the callback if timeFromNow is < 0 @@ -92,9 +92,10 @@ define(function (require) { * The callback should only be called until maxIterations is reached */ if (timeFromNow > 0 && self.iterations <= self.maxIterations) { - self.callback(timeFromNow);} + self.callback(timeFromNow); + } }, - 'frequency' : this._calcFreq() + frequency: this._calcFreq(), }); }; @@ -104,7 +105,7 @@ define(function (require) { * @for p5.SoundLoop * @param {Number} [timeFromNow] schedule a starting time */ - p5.SoundLoop.prototype.start = function(timeFromNow) { + p5.SoundLoop.prototype.start = function (timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; if (!this.isPlaying) { @@ -119,7 +120,7 @@ define(function (require) { * @for p5.SoundLoop * @param {Number} [timeFromNow] schedule a stopping time */ - p5.SoundLoop.prototype.stop = function(timeFromNow) { + p5.SoundLoop.prototype.stop = function (timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; if (this.isPlaying) { @@ -133,7 +134,7 @@ define(function (require) { * @for p5.SoundLoop * @param {Number} [timeFromNow] schedule a pausing time */ - p5.SoundLoop.prototype.pause = function(timeFromNow) { + p5.SoundLoop.prototype.pause = function (timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; if (this.isPlaying) { @@ -142,7 +143,6 @@ define(function (require) { } }; - /** * Synchronize loops. Use this method to start two or more loops in synchronization * or to start a loop in synchronization with a loop that is already playing @@ -154,7 +154,7 @@ define(function (require) { * @param {Object} otherLoop a p5.SoundLoop to sync with * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds */ - p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) { + p5.SoundLoop.prototype.syncedStart = function (otherLoop, timeFromNow) { var t = timeFromNow || 0; var now = p5sound.audiocontext.currentTime; @@ -170,14 +170,13 @@ define(function (require) { } }; - /** * Updates frequency value, reflected in next callback * @private * @for p5.SoundLoop * @method _update */ - p5.SoundLoop.prototype._update = function() { + p5.SoundLoop.prototype._update = function () { this.clock.frequency.value = this._calcFreq(); }; @@ -188,7 +187,7 @@ define(function (require) { * @method _calcFreq * @return {Number} new clock frequency value */ - p5.SoundLoop.prototype._calcFreq = function() { + p5.SoundLoop.prototype._calcFreq = function () { //Seconds mode, bpm / timesignature has no effect if (typeof this._interval === 'number') { this.musicalTimeMode = false; @@ -197,7 +196,10 @@ define(function (require) { //Musical timing mode, calculate interval based bpm, interval,and time signature else if (typeof this._interval === 'string') { this.musicalTimeMode = true; - return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4); + return ( + (this._bpm / 60 / this._convertNotation(this._interval)) * + (this._timeSignature / 4) + ); } }; @@ -210,17 +212,19 @@ define(function (require) { * @param {String} value value to be converted * @return {Number} converted value in seconds */ - p5.SoundLoop.prototype._convertNotation = function(value) { + p5.SoundLoop.prototype._convertNotation = function (value) { var type = value.slice(-1); - value = Number(value.slice(0,-1)); + value = Number(value.slice(0, -1)); switch (type) { case 'm': return this._measure(value); case 'n': return this._note(value); default: - console.warn('Specified interval is not formatted correctly. See Tone.js '+ - 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time'); + console.warn( + 'Specified interval is not formatted correctly. See Tone.js ' + + 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time' + ); } }; @@ -230,7 +234,7 @@ define(function (require) { * @for p5.SoundLoop * @method _measure */ - p5.SoundLoop.prototype._measure = function(value) { + p5.SoundLoop.prototype._measure = function (value) { return value * this._timeSignature; }; @@ -239,11 +243,10 @@ define(function (require) { * @method _note * @for p5.SoundLoop */ - p5.SoundLoop.prototype._note = function(value) { - return this._timeSignature / value ; + p5.SoundLoop.prototype._note = function (value) { + return this._timeSignature / value; }; - /** * Getters and Setters, setting any paramter will result in a change in the clock's * frequency, that will be reflected after the next callback @@ -252,19 +255,21 @@ define(function (require) { * @for p5.SoundLoop */ Object.defineProperty(p5.SoundLoop.prototype, 'bpm', { - get : function() { + get: function () { return this._bpm; }, - set : function(bpm) { + set: function (bpm) { if (!this.musicalTimeMode) { - 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)'); + 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)' + ); } this._bpm = bpm; this._update(); - } + }, }); /** @@ -273,19 +278,21 @@ define(function (require) { * @for p5.SoundLoop */ Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', { - get : function() { + get: function () { return this._timeSignature; }, - set : function(timeSig) { + set: function (timeSig) { if (!this.musicalTimeMode) { - 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)'); + 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)' + ); } this._timeSignature = timeSig; this._update(); - } + }, }); /** @@ -294,14 +301,14 @@ define(function (require) { * @for p5.SoundLoop */ Object.defineProperty(p5.SoundLoop.prototype, 'interval', { - get : function() { + get: function () { return this._interval; }, - set : function(interval) { - this.musicalTimeMode = typeof interval === 'Number'? false : true; + set: function (interval) { + this.musicalTimeMode = typeof interval === 'Number' ? false : true; this._interval = interval; this._update(); - } + }, }); /** @@ -311,9 +318,9 @@ define(function (require) { * @readonly */ Object.defineProperty(p5.SoundLoop.prototype, 'iterations', { - get : function() { + get: function () { return this.clock.ticks; - } + }, }); return p5.SoundLoop; diff --git a/src/soundRecorder.js b/src/soundRecorder.js index 6f50a469..0ade5b1c 100644 --- a/src/soundRecorder.js +++ b/src/soundRecorder.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - // inspiration: recorder.js, Tone.js & typedarray.org const p5sound = require('master'); @@ -83,7 +82,7 @@ define(function (require) { * } * */ - p5.SoundRecorder = function() { + p5.SoundRecorder = function () { this.input = ac.createGain(); this.output = ac.createGain(); @@ -92,19 +91,23 @@ define(function (require) { const workletBufferSize = safeBufferSize(1024); - this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, { - outputChannelCount: [this._outputChannels], - processorOptions: { - numInputChannels: this._inputChannels, - bufferSize: workletBufferSize + this._workletNode = new AudioWorkletNode( + ac, + processorNames.recorderProcessor, + { + outputChannelCount: [this._outputChannels], + processorOptions: { + numInputChannels: this._inputChannels, + bufferSize: workletBufferSize, + }, } - }); + ); - this._workletNode.port.onmessage = function(event) { + this._workletNode.port.onmessage = function (event) { if (event.data.name === 'buffers') { const buffers = [ new Float32Array(event.data.leftBuffer), - new Float32Array(event.data.rightBuffer) + new Float32Array(event.data.rightBuffer), ]; this._callback(buffers); } @@ -115,7 +118,7 @@ define(function (require) { * @private * @type Function(Float32Array) */ - this._callback = function() {}; + this._callback = function () {}; // connections this._workletNode.connect(p5.soundOut._silentNode); @@ -135,7 +138,7 @@ define(function (require) { * @param {Object} [unit] p5.sound object or a web audio unit * that outputs sound */ - p5.SoundRecorder.prototype.setInput = function(unit) { + p5.SoundRecorder.prototype.setInput = function (unit) { this.input.disconnect(); this.input = null; this.input = ac.createGain(); @@ -164,17 +167,16 @@ define(function (require) { * @param {Function} [callback] The name of a function that will be * called once the recording completes */ - p5.SoundRecorder.prototype.record = function(sFile, duration, callback) { + p5.SoundRecorder.prototype.record = function (sFile, duration, callback) { this._workletNode.port.postMessage({ name: 'start', duration: duration }); if (sFile && callback) { - this._callback = function(buffer) { + this._callback = function (buffer) { sFile.setBuffer(buffer); callback(); }; - } - else if (sFile) { - this._callback = function(buffer) { + } else if (sFile) { + this._callback = function (buffer) { sFile.setBuffer(buffer); }; } @@ -189,16 +191,16 @@ define(function (require) { * @method stop * @for p5.SoundRecorder */ - p5.SoundRecorder.prototype.stop = function() { + p5.SoundRecorder.prototype.stop = function () { this._workletNode.port.postMessage({ name: 'stop' }); }; - p5.SoundRecorder.prototype.dispose = function() { + p5.SoundRecorder.prototype.dispose = function () { // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); - this._callback = function() {}; + this._callback = function () {}; if (this.input) { this.input.disconnect(); } @@ -206,7 +208,6 @@ define(function (require) { this._workletNode = null; }; - /** * Save a p5.SoundFile as a .wav file. The browser will prompt the user * to download the file to their device. diff --git a/src/soundfile.js b/src/soundfile.js index d394e56c..137e2ae5 100644 --- a/src/soundfile.js +++ b/src/soundfile.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - const CustomError = require('errorHandler'); const p5sound = require('master'); const ac = p5sound.audiocontext; @@ -65,14 +64,15 @@ define(function (require) { * } * */ - p5.SoundFile = function(paths, onload, onerror, whileLoading) { + p5.SoundFile = function (paths, onload, onerror, whileLoading) { if (typeof paths !== 'undefined') { if (typeof paths === 'string' || typeof paths[0] === 'string') { var path = p5.prototype._checkFileFormats(paths); this.url = path; - } - else if(typeof paths === 'object') { - if (!(window.File && window.FileReader && window.FileList && window.Blob)) { + } else if (typeof paths === 'object') { + if ( + !(window.File && window.FileReader && window.FileList && window.Blob) + ) { // The File API isn't supported in this browser throw 'Unable to load file because the File API is not supported'; } @@ -87,7 +87,7 @@ define(function (require) { } // private _onended callback, set by the method: onended(callback) - this._onended = function() {}; + this._onended = function () {}; this._looping = false; this._playing = false; @@ -143,7 +143,7 @@ define(function (require) { if (typeof whileLoading === 'function') { this._whileLoading = whileLoading; } else { - this._whileLoading = function() {}; + this._whileLoading = function () {}; } this._clearOnEnd = _clearOnEnd.bind(this); @@ -197,22 +197,32 @@ define(function (require) { * } * */ - p5.prototype.loadSound = function(path, callback, onerror, whileLoading) { + p5.prototype.loadSound = function (path, callback, onerror, whileLoading) { // if loading locally without a server - if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) { - window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); + if ( + window.location.origin.indexOf('file://') > -1 && + window.cordova === 'undefined' + ) { + window.alert( + 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS' + ); } var self = this; - var s = new p5.SoundFile(path, function() { - if(typeof callback === 'function') { - callback.apply(self, arguments); - } + var s = new p5.SoundFile( + path, + function () { + if (typeof callback === 'function') { + callback.apply(self, arguments); + } - if (typeof self._decrementPreload === 'function') { - self._decrementPreload(); - } - }, onerror, whileLoading); + if (typeof self._decrementPreload === 'function') { + self._decrementPreload(); + } + }, + onerror, + whileLoading + ); return s; }; @@ -227,25 +237,30 @@ define(function (require) { * @param {Function} [successCallback] Name of a function to call once file loads * @param {Function} [errorCallback] Name of a function to call if there is an error */ - p5.SoundFile.prototype.load = function(callback, errorCallback) { + p5.SoundFile.prototype.load = function (callback, errorCallback) { var self = this; var errorTrace = new Error().stack; if (this.url !== undefined && this.url !== '') { var request = new XMLHttpRequest(); - request.addEventListener('progress', function(evt) { - self._updateProgress(evt); - }, false); + request.addEventListener( + 'progress', + function (evt) { + self._updateProgress(evt); + }, + false + ); request.open('GET', this.url, true); request.responseType = 'arraybuffer'; - request.onload = function() { + request.onload = function () { if (request.status === 200) { // on sucess loading file: if (!self.panner) return; - ac.decodeAudioData(request.response, + ac.decodeAudioData( + request.response, // success decoding buffer: - function(buff) { + function (buff) { if (!self.panner) return; self.buffer = buff; self.panner.inputChannels(buff.numberOfChannels); @@ -254,15 +269,21 @@ define(function (require) { } }, // error decoding buffer. "e" is undefined in Chrome 11/22/2015 - function() { + function () { if (!self.panner) return; - var err = new CustomError('decodeAudioData', errorTrace, self.url); + var err = new CustomError( + 'decodeAudioData', + errorTrace, + self.url + ); var msg = 'AudioContext error at decodeAudioData for ' + self.url; if (errorCallback) { err.msg = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } } ); @@ -271,38 +292,50 @@ define(function (require) { else { if (!self.panner) return; var err = new CustomError('loadSound', errorTrace, self.url); - var msg = 'Unable to load ' + self.url + '. The request status was: ' + - request.status + ' (' + request.statusText + ')'; + var msg = + 'Unable to load ' + + self.url + + '. The request status was: ' + + request.status + + ' (' + + request.statusText + + ')'; if (errorCallback) { err.message = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } } }; // if there is another error, aside from 404... - request.onerror = function() { + request.onerror = function () { var err = new CustomError('loadSound', errorTrace, self.url); - var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.'; + var msg = + 'There was no response from the server at ' + + self.url + + '. Check the url and internet connectivity.'; if (errorCallback) { err.message = msg; errorCallback(err); } else { - console.error(msg +'\n The error stack trace includes: \n' + err.stack); + console.error( + msg + '\n The error stack trace includes: \n' + err.stack + ); } }; request.send(); - } - else if (this.file !== undefined) { + } else if (this.file !== undefined) { var reader = new FileReader(); - reader.onload = function() { + reader.onload = function () { if (!self.panner) return; - ac.decodeAudioData(reader.result, function(buff) { + ac.decodeAudioData(reader.result, function (buff) { if (!self.panner) return; self.buffer = buff; self.panner.inputChannels(buff.numberOfChannels); @@ -311,7 +344,7 @@ define(function (require) { } }); }; - reader.onerror = function(e) { + reader.onerror = function (e) { if (!self.panner) return; if (onerror) { onerror(e); @@ -322,9 +355,9 @@ define(function (require) { }; // TO DO: use this method to create a loading bar that shows progress during file upload/decode. - p5.SoundFile.prototype._updateProgress = function(evt) { + p5.SoundFile.prototype._updateProgress = function (evt) { if (evt.lengthComputable) { - var percentComplete = evt.loaded / evt.total * 0.99; + var percentComplete = (evt.loaded / evt.total) * 0.99; this._whileLoading(percentComplete, evt); // ... } else { @@ -340,7 +373,7 @@ define(function (require) { * @for p5.SoundFile * @return {Boolean} */ - p5.SoundFile.prototype.isLoaded = function() { + p5.SoundFile.prototype.isLoaded = function () { if (this.buffer) { return true; } else { @@ -360,7 +393,13 @@ define(function (require) { * @param {Number} [cueStart] (optional) cue start time in seconds * @param {Number} [duration] (optional) duration of playback in seconds */ - p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) { + p5.SoundFile.prototype.play = function ( + startTime, + rate, + amp, + _cueStart, + duration + ) { if (!this.output) { console.warn('SoundFile.play() called after dispose'); return; @@ -406,17 +445,22 @@ define(function (require) { this._counterNode = this._initCounterNode(); if (_cueStart) { - if (_cueStart >=0 && _cueStart < this.buffer.duration) { + if (_cueStart >= 0 && _cueStart < this.buffer.duration) { // this.startTime = cueStart; cueStart = _cueStart; - } else { throw 'start time out of range'; } + } else { + throw 'start time out of range'; + } } else { cueStart = 0; } if (duration) { // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error - duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration; + duration = + duration <= this.buffer.duration - cueStart + ? duration + : this.buffer.duration; } // if it was paused, play at the pause position @@ -453,10 +497,8 @@ define(function (require) { this._counterNode.loopStart = cueStart; this._counterNode.loopEnd = cueEnd; } - }; - /** * p5.SoundFile has two play modes: restart and * sustain. Play Mode determines what happens to a @@ -497,7 +539,7 @@ define(function (require) { * * */ - p5.SoundFile.prototype.playMode = function(str) { + p5.SoundFile.prototype.playMode = function (str) { var s = str.toLowerCase(); // if restart, stop all other sounds from playing @@ -553,7 +595,7 @@ define(function (require) { * * */ - p5.SoundFile.prototype.pause = function(startTime) { + p5.SoundFile.prototype.pause = function (startTime) { var now = p5sound.audiocontext.currentTime; var time = startTime || 0; var pTime = time + now; @@ -611,7 +653,13 @@ define(function (require) { * * */ - p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) { + p5.SoundFile.prototype.loop = function ( + startTime, + rate, + amp, + loopStart, + duration + ) { this._looping = true; this.play(startTime, rate, amp, loopStart, duration); }; @@ -625,14 +673,12 @@ define(function (require) { * @for p5.SoundFile * @param {Boolean} Boolean set looping to true or false */ - p5.SoundFile.prototype.setLoop = function(bool) { + p5.SoundFile.prototype.setLoop = function (bool) { if (bool === true) { this._looping = true; - } - else if (bool === false) { + } else if (bool === false) { this._looping = false; - } - else { + } else { throw 'Error: setLoop accepts either true or false'; } if (this.bufferSourceNode) { @@ -648,7 +694,7 @@ define(function (require) { * @for p5.SoundFile * @return {Boolean} */ - p5.SoundFile.prototype.isLooping = function() { + p5.SoundFile.prototype.isLooping = function () { if (!this.bufferSourceNode) { return false; } @@ -666,7 +712,7 @@ define(function (require) { * @for p5.SoundFile * @return {Boolean} */ - p5.SoundFile.prototype.isPlaying = function() { + p5.SoundFile.prototype.isPlaying = function () { return this._playing; }; @@ -678,7 +724,7 @@ define(function (require) { * @for p5.SoundFile * @return {Boolean} */ - p5.SoundFile.prototype.isPaused = function() { + p5.SoundFile.prototype.isPaused = function () { return this._paused; }; @@ -690,7 +736,7 @@ define(function (require) { * @param {Number} [startTime] (optional) schedule event to occur * in seconds from now */ - p5.SoundFile.prototype.stop = function(timeFromNow) { + p5.SoundFile.prototype.stop = function (timeFromNow) { var time = timeFromNow || 0; if (this.mode === 'sustain' || this.mode === 'untildone') { @@ -698,8 +744,7 @@ define(function (require) { this._playing = false; this.pauseTime = 0; this._paused = false; - } - else if (this.buffer && this.bufferSourceNode) { + } else if (this.buffer && this.bufferSourceNode) { var now = p5sound.audiocontext.currentTime; var t = time || 0; this.pauseTime = 0; @@ -714,16 +759,16 @@ define(function (require) { * Stop playback on all of this soundfile's sources. * @private */ - p5.SoundFile.prototype.stopAll = function(_time) { + p5.SoundFile.prototype.stopAll = function (_time) { var now = p5sound.audiocontext.currentTime; var time = _time || 0; if (this.buffer && this.bufferSourceNode) { for (var i in this.bufferSourceNodes) { const bufferSourceNode = this.bufferSourceNodes[i]; - if (!!bufferSourceNode) { + if (bufferSourceNode) { try { bufferSourceNode.stop(now + time); - } catch(e) { + } catch (e) { // this was throwing errors only on Safari } } @@ -752,7 +797,7 @@ define(function (require) { * @param {Number} [timeFromNow] Schedule this event to happen at * t seconds in the future */ - p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) { + p5.SoundFile.prototype.setVolume = function (vol, _rampTime, _tFromNow) { if (typeof vol === 'number') { var rampTime = _rampTime || 0; var tFromNow = _tFromNow || 0; @@ -761,8 +806,7 @@ define(function (require) { this.output.gain.cancelScheduledValues(now + tFromNow); this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow); this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); - } - else if (vol) { + } else if (vol) { vol.connect(this.output.gain); } else { // return the Gain Node @@ -776,7 +820,7 @@ define(function (require) { // these are the same thing p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume; - p5.SoundFile.prototype.getVolume = function() { + p5.SoundFile.prototype.getVolume = function () { return this.output.gain.value; }; @@ -817,7 +861,7 @@ define(function (require) { * } * */ - p5.SoundFile.prototype.pan = function(pval, tFromNow) { + p5.SoundFile.prototype.pan = function (pval, tFromNow) { this.panPosition = pval; this.panner.pan(pval, tFromNow); }; @@ -831,7 +875,7 @@ define(function (require) { * as a number between -1.0 (left) and 1.0 (right). * 0.0 is center and default. */ - p5.SoundFile.prototype.getPan = function() { + p5.SoundFile.prototype.getPan = function () { return this.panPosition; }; @@ -879,7 +923,7 @@ define(function (require) { * * */ - p5.SoundFile.prototype.rate = function(playbackRate) { + p5.SoundFile.prototype.rate = function (playbackRate) { var reverse = false; if (typeof playbackRate === 'undefined') { return this.playbackRate; @@ -889,23 +933,25 @@ define(function (require) { if (playbackRate === 0) { playbackRate = 0.0000000000001; - } - - else if (playbackRate < 0 && !this.reversed) { + } else if (playbackRate < 0 && !this.reversed) { playbackRate = Math.abs(playbackRate); reverse = true; - } - - else if (playbackRate > 0 && this.reversed) { + } else if (playbackRate > 0 && this.reversed) { reverse = true; } if (this.bufferSourceNode) { var now = p5sound.audiocontext.currentTime; this.bufferSourceNode.playbackRate.cancelScheduledValues(now); - this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now); + this.bufferSourceNode.playbackRate.linearRampToValueAtTime( + Math.abs(playbackRate), + now + ); this._counterNode.playbackRate.cancelScheduledValues(now); - this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now); + this._counterNode.playbackRate.linearRampToValueAtTime( + Math.abs(playbackRate), + now + ); } if (reverse) { @@ -915,12 +961,12 @@ define(function (require) { }; // TO DO: document this - p5.SoundFile.prototype.setPitch = function(num) { + p5.SoundFile.prototype.setPitch = function (num) { var newPlaybackRate = midiToFreq(num) / midiToFreq(60); this.rate(newPlaybackRate); }; - p5.SoundFile.prototype.getPlaybackRate = function() { + p5.SoundFile.prototype.getPlaybackRate = function () { return this.playbackRate; }; @@ -931,7 +977,7 @@ define(function (require) { * @for p5.SoundFile * @return {Number} The duration of the soundFile in seconds. */ - p5.SoundFile.prototype.duration = function() { + p5.SoundFile.prototype.duration = function () { // Return Duration if (this.buffer) { return this.buffer.duration; @@ -949,7 +995,7 @@ define(function (require) { * @for p5.SoundFile * @return {Number} currentTime of the soundFile in seconds. */ - p5.SoundFile.prototype.currentTime = function() { + p5.SoundFile.prototype.currentTime = function () { return this.reversed ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate : this._lastPos / ac.sampleRate; @@ -967,7 +1013,7 @@ define(function (require) { * @param {Number} cueTime cueTime of the soundFile in seconds. * @param {Number} duration duration in seconds. */ - p5.SoundFile.prototype.jump = function(cueTime, duration) { + p5.SoundFile.prototype.jump = function (cueTime, duration) { if (cueTime < 0 || cueTime > this.buffer.duration) { throw 'jump time out of range'; } @@ -984,37 +1030,37 @@ define(function (require) { }; /** - * Return the number of channels in a sound file. - * For example, Mono = 1, Stereo = 2. - * - * @method channels - * @for p5.SoundFile - * @return {Number} [channels] - */ - p5.SoundFile.prototype.channels = function() { + * Return the number of channels in a sound file. + * For example, Mono = 1, Stereo = 2. + * + * @method channels + * @for p5.SoundFile + * @return {Number} [channels] + */ + p5.SoundFile.prototype.channels = function () { return this.buffer.numberOfChannels; }; /** - * Return the sample rate of the sound file. - * - * @method sampleRate - * @for p5.SoundFile - * @return {Number} [sampleRate] - */ - p5.SoundFile.prototype.sampleRate = function() { + * Return the sample rate of the sound file. + * + * @method sampleRate + * @for p5.SoundFile + * @return {Number} [sampleRate] + */ + p5.SoundFile.prototype.sampleRate = function () { return this.buffer.sampleRate; }; /** - * Return the number of samples in a sound file. - * Equal to sampleRate * duration. - * - * @method frames - * @for p5.SoundFile - * @return {Number} [sampleCount] - */ - p5.SoundFile.prototype.frames = function() { + * Return the number of samples in a sound file. + * Equal to sampleRate * duration. + * + * @method frames + * @for p5.SoundFile + * @return {Number} [sampleCount] + */ + p5.SoundFile.prototype.frames = function () { return this.buffer.length; }; @@ -1034,12 +1080,11 @@ define(function (require) { * Defaults to 5*width of the browser window. * @returns {Float32Array} Array of peaks. */ - p5.SoundFile.prototype.getPeaks = function(length) { - + p5.SoundFile.prototype.getPeaks = function (length) { if (this.buffer) { // set length to window's width if no length is provided if (!length) { - length = window.width*5; + length = window.width * 5; } if (this.buffer) { var buffer = this.buffer; @@ -1051,14 +1096,14 @@ define(function (require) { for (var c = 0; c < channels; c++) { var chan = buffer.getChannelData(c); for (var i = 0; i < length; i++) { - var start = ~~(i*sampleSize); + var start = ~~(i * sampleSize); var end = ~~(start + sampleSize); var max = 0; - for (var j = start; j < end; j+= sampleStep) { + for (var j = start; j < end; j += sampleStep) { var value = chan[j]; if (value > max) { max = value; - // faster than Math.abs + // faster than Math.abs } else if (-value > max) { max = value; } @@ -1071,9 +1116,7 @@ define(function (require) { return peaks; } - } - - else { + } else { throw 'Cannot load peaks yet, buffer is not loaded'; } }; @@ -1106,7 +1149,7 @@ define(function (require) { * * */ - p5.SoundFile.prototype.reverseBuffer = function() { + p5.SoundFile.prototype.reverseBuffer = function () { if (this.buffer) { var currentPos = this._lastPos / ac.sampleRate; var curVol = this.getVolume(); @@ -1140,16 +1183,16 @@ define(function (require) { * @param {Function} callback function to call when the * soundfile has ended. */ - p5.SoundFile.prototype.onended = function(callback) { + p5.SoundFile.prototype.onended = function (callback) { this._onended = callback; return this; }; - p5.SoundFile.prototype.add = function() { + p5.SoundFile.prototype.add = function () { // TO DO }; - p5.SoundFile.prototype.dispose = function() { + p5.SoundFile.prototype.dispose = function () { var now = p5sound.audiocontext.currentTime; // remove reference to soundfile @@ -1163,16 +1206,16 @@ define(function (require) { this.bufferSourceNodes[i].disconnect(); try { this.bufferSourceNodes[i].stop(now); - } catch(e) { + } catch (e) { console.warn('no buffer source node to dispose'); } this.bufferSourceNodes[i] = null; } } - if ( this.isPlaying() ) { + if (this.isPlaying()) { try { this._counterNode.stop(now); - } catch(e) { + } catch (e) { console.log(e); } this._counterNode = null; @@ -1199,11 +1242,10 @@ define(function (require) { * @for p5.SoundFile * @param {Object} [object] Audio object that accepts an input */ - p5.SoundFile.prototype.connect = function(unit) { + p5.SoundFile.prototype.connect = function (unit) { if (!unit) { this.panner.connect(p5sound.input); - } - else { + } else { if (unit.hasOwnProperty('input')) { this.panner.connect(unit.input); } else { @@ -1218,7 +1260,7 @@ define(function (require) { * @method disconnect * @for p5.SoundFile */ - p5.SoundFile.prototype.disconnect = function() { + p5.SoundFile.prototype.disconnect = function () { if (this.panner) { this.panner.disconnect(); } @@ -1226,8 +1268,10 @@ define(function (require) { /** */ - p5.SoundFile.prototype.getLevel = function() { - console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead'); + p5.SoundFile.prototype.getLevel = function () { + console.warn( + 'p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead' + ); }; /** @@ -1239,7 +1283,7 @@ define(function (require) { * @param {String} path path to audio file * @param {Function} callback Callback */ - p5.SoundFile.prototype.setPath = function(p, callback) { + p5.SoundFile.prototype.setPath = function (p, callback) { var path = p5.prototype._checkFileFormats(p); this.url = path; this.load(callback); @@ -1254,7 +1298,7 @@ define(function (require) { * will create a stereo source. 1 will create * a mono source. */ - p5.SoundFile.prototype.setBuffer = function(buf) { + p5.SoundFile.prototype.setBuffer = function (buf) { var numChannels = buf.length; var size = buf[0].length; var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate); @@ -1264,7 +1308,7 @@ define(function (require) { } for (var channelNum = 0; channelNum < numChannels; channelNum++) { - var channel = newBuffer.getChannelData( channelNum ); + var channel = newBuffer.getChannelData(channelNum); channel.set(buf[channelNum]); } @@ -1282,9 +1326,9 @@ define(function (require) { // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0 //////////////////////////////////////////////////////////////////////////////////// - var _createCounterBuffer = function(buffer) { + var _createCounterBuffer = function (buffer) { const len = buffer.length; - const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate ); + const audioBuf = ac.createBuffer(1, buffer.length, ac.sampleRate); const arrayBuffer = audioBuf.getChannelData(0); for (var index = 0; index < len; index++) { arrayBuffer[index] = index; @@ -1293,7 +1337,7 @@ define(function (require) { }; // initialize counterNode, set its initial buffer and playbackRate - p5.SoundFile.prototype._initCounterNode = function() { + p5.SoundFile.prototype._initCounterNode = function () { var self = this; var now = ac.currentTime; var cNode = ac.createBufferSource(); @@ -1305,10 +1349,14 @@ define(function (require) { self._workletNode.disconnect(); delete self._workletNode; } - self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor, { - processorOptions: { bufferSize: workletBufferSize } - }); - self._workletNode.port.onmessage = event => { + self._workletNode = new AudioWorkletNode( + ac, + processorNames.soundFileProcessor, + { + processorOptions: { bufferSize: workletBufferSize }, + } + ); + self._workletNode.port.onmessage = (event) => { if (event.data.name === 'position') { // event.data.position should only be 0 when paused if (event.data.position === 0) { @@ -1322,7 +1370,7 @@ define(function (require) { }; // create counter buffer of the same length as self.buffer - cNode.buffer = _createCounterBuffer( self.buffer ); + cNode.buffer = _createCounterBuffer(self.buffer); cNode.playbackRate.setValueAtTime(self.playbackRate, now); @@ -1333,7 +1381,7 @@ define(function (require) { }; // initialize sourceNode, set its initial buffer and playbackRate - p5.SoundFile.prototype._initSourceNode = function() { + p5.SoundFile.prototype._initSourceNode = function () { var bufferSourceNode = ac.createBufferSource(); bufferSourceNode.buffer = this.buffer; bufferSourceNode.playbackRate.value = this.playbackRate; @@ -1359,7 +1407,12 @@ define(function (require) { * @param {Number} [minPeaks] minimum number of peaks defaults to 200 * @return {Array} Array of timestamped peaks */ - p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) { + p5.SoundFile.prototype.processPeaks = function ( + callback, + _initThreshold, + _minThreshold, + _minPeaks + ) { var bufLen = this.buffer.length; var sampleRate = this.buffer.sampleRate; var buffer = this.buffer; @@ -1388,32 +1441,37 @@ define(function (require) { offlineContext.startRendering(); // Render the song // act on the result - offlineContext.oncomplete = function(e) { + offlineContext.oncomplete = function (e) { if (!self.panner) return; var filteredBuffer = e.renderedBuffer; var bufferData = filteredBuffer.getChannelData(0); - // step 1: // create Peak instances, add them to array, with strength and sampleIndex do { allPeaks = getPeaksAtThreshold(bufferData, threshold); threshold -= 0.005; - } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold); - + } while ( + Object.keys(allPeaks).length < minPeaks && + threshold >= minThreshold + ); // step 2: // find intervals for each peak in the sampleIndex, add tempos array var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks); // step 3: find top tempos - var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate); + var groups = groupNeighborsByTempo( + intervalCounts, + filteredBuffer.sampleRate + ); // sort top intervals - var topTempos = groups.sort(function(intA, intB) { - return intB.count - intA.count; - - }).splice(0,5); + var topTempos = groups + .sort(function (intA, intB) { + return intB.count - intA.count; + }) + .splice(0, 5); // set this SoundFile's tempo to the top tempo ?? this.tempo = topTempos[0].tempo; @@ -1421,14 +1479,19 @@ define(function (require) { // step 4: // new array of peaks at top tempo within a bpmVariance var bpmVariance = 5; - var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance); + var tempoPeaks = getPeaksAtTopTempo( + allPeaks, + topTempos[0].tempo, + filteredBuffer.sampleRate, + bpmVariance + ); callback(tempoPeaks); }; }; // process peaks - var Peak = function(amp, i) { + var Peak = function (amp, i) { this.sampleIndex = i; this.amplitude = amp; this.tempos = []; @@ -1460,7 +1523,6 @@ define(function (require) { var peaksArray = Object.keys(peaksObj).sort(); for (var index = 0; index < peaksArray.length; index++) { - // find intervals in comparison to nearby peaks for (var i = 0; i < 10; i++) { var startPeak = peaksObj[peaksArray[index]]; @@ -1469,7 +1531,7 @@ define(function (require) { if (startPeak && endPeak) { var startPos = startPeak.sampleIndex; var endPos = endPeak.sampleIndex; - var interval = endPos - startPos; + var interval = endPos - startPos; // add a sample interval to the startPeak in the allPeaks array if (interval > 0) { @@ -1477,7 +1539,7 @@ define(function (require) { } // tally the intervals and return interval counts - var foundInterval = intervalCounts.some(function(intervalCount) { + var foundInterval = intervalCounts.some(function (intervalCount) { if (intervalCount.interval === interval) { intervalCount.count++; return intervalCount; @@ -1498,22 +1560,22 @@ define(function (require) { return intervalCounts; } - // 3. for processPeaks --> find tempo function groupNeighborsByTempo(intervalCounts, sampleRate) { var tempoCounts = []; - intervalCounts.forEach(function(intervalCount) { - + intervalCounts.forEach(function (intervalCount) { try { // Convert an interval to tempo - var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) ); + var theoreticalTempo = Math.abs( + 60 / (intervalCount.interval / sampleRate) + ); theoreticalTempo = mapTempo(theoreticalTempo); - var foundTempo = tempoCounts.some(function(tempoCount) { + var foundTempo = tempoCounts.some(function (tempoCount) { if (tempoCount.tempo === theoreticalTempo) - return tempoCount.count += intervalCount.count; + return (tempoCount.count += intervalCount.count); }); if (!foundTempo) { if (isNaN(theoreticalTempo)) { @@ -1521,13 +1583,12 @@ define(function (require) { } tempoCounts.push({ tempo: Math.round(theoreticalTempo), - count: intervalCount.count + count: intervalCount.count, }); } - } catch(e) { + } catch (e) { throw e; } - }); return tempoCounts; @@ -1544,19 +1605,21 @@ define(function (require) { var peak = peaksObj[key]; for (var j = 0; j < peak.intervals.length; j++) { - var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) ); + var intervalBPM = Math.round( + Math.abs(60 / (peak.intervals[j] / sampleRate)) + ); intervalBPM = mapTempo(intervalBPM); - if ( Math.abs(intervalBPM - tempo) < bpmVariance ) { + if (Math.abs(intervalBPM - tempo) < bpmVariance) { // convert sampleIndex to seconds - peaksAtTopTempo.push(peak.sampleIndex/sampleRate); + peaksAtTopTempo.push(peak.sampleIndex / sampleRate); } } } // filter out peaks that are very close to each other - peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) { + peaksAtTopTempo = peaksAtTopTempo.filter(function (peakTime, index, arr) { var dif = arr[index + 1] - peakTime; if (dif > 0.01) { return true; @@ -1569,23 +1632,23 @@ define(function (require) { // helper function for processPeaks function mapTempo(theoreticalTempo) { // these scenarios create infinite while loop - if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) { + if (!isFinite(theoreticalTempo) || theoreticalTempo === 0) { return; } // Adjust the tempo to fit within the 90-180 BPM range while (theoreticalTempo < 90) theoreticalTempo *= 2; - while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2; + while (theoreticalTempo > 180 && theoreticalTempo > 90) + theoreticalTempo /= 2; return theoreticalTempo; } - /*** SCHEDULE EVENTS ***/ // Cue inspired by JavaScript setTimeout, and the // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org - var Cue = function(callback, time, id, val) { + var Cue = function (callback, time, id, val) { this.callback = callback; this.time = time; this.id = id; @@ -1651,7 +1714,7 @@ define(function (require) { * } * */ - p5.SoundFile.prototype.addCue = function(time, callback, val) { + p5.SoundFile.prototype.addCue = function (time, callback, val) { var id = this._cueIDCounter++; var cue = new Cue(callback, time, id, val); @@ -1672,7 +1735,7 @@ define(function (require) { * @for p5.SoundFile * @param {Number} id ID of the cue, as returned by addCue */ - p5.SoundFile.prototype.removeCue = function(id) { + p5.SoundFile.prototype.removeCue = function (id) { var cueLength = this._cues.length; for (var i = 0; i < cueLength; i++) { var cue = this._cues[i]; @@ -1694,28 +1757,29 @@ define(function (require) { * * @method clearCues */ - p5.SoundFile.prototype.clearCues = function() { + p5.SoundFile.prototype.clearCues = function () { this._cues = []; // this.elt.ontimeupdate = null; }; // private method that checks for cues to be fired if events // have been scheduled using addCue(callback, time). - p5.SoundFile.prototype._onTimeUpdate = function(position) { - var playbackTime = position/this.buffer.sampleRate; + p5.SoundFile.prototype._onTimeUpdate = function (position) { + var playbackTime = position / this.buffer.sampleRate; var cueLength = this._cues.length; - for (var i = 0 ; i < cueLength; i++) { + for (var i = 0; i < cueLength; i++) { var cue = this._cues[i]; var callbackTime = cue.time; var val = cue.val; - if (~~this._prevUpdateTime <= callbackTime && callbackTime <= playbackTime) { - + if ( + ~~this._prevUpdateTime <= callbackTime && + callbackTime <= playbackTime + ) { // pass the scheduled callbackTime as parameter to the callback cue.callback(val); } - } this._prevUpdateTime = playbackTime; @@ -1747,7 +1811,7 @@ define(function (require) { * } * */ - p5.SoundFile.prototype.save = function(fileName) { + p5.SoundFile.prototype.save = function (fileName) { p5.prototype.saveSound(this, fileName, 'wav'); }; @@ -1802,7 +1866,7 @@ define(function (require) { * * */ - p5.SoundFile.prototype.getBlob = function() { + p5.SoundFile.prototype.getBlob = function () { const dataView = convertToWav(this.buffer); return new Blob([dataView], { type: 'audio/wav' }); }; @@ -1821,13 +1885,16 @@ define(function (require) { // delete bufferSourceNode(s) in soundFile.bufferSourceNodes // iterate in reverse order because the index changes by splice - soundFile.bufferSourceNodes.map((_, i) => i).reverse().forEach(function (i) { - const n = soundFile.bufferSourceNodes[i]; - - if (n._playing === false) { - soundFile.bufferSourceNodes.splice(i, 1); - } - }); + soundFile.bufferSourceNodes + .map((_, i) => i) + .reverse() + .forEach(function (i) { + const n = soundFile.bufferSourceNodes[i]; + + if (n._playing === false) { + soundFile.bufferSourceNodes.splice(i, 1); + } + }); if (soundFile.bufferSourceNodes.length === 0) { soundFile._playing = false; diff --git a/test/tests/p5.Amplitude.js b/test/tests/p5.Amplitude.js index 0ea20522..1be92ddf 100644 --- a/test/tests/p5.Amplitude.js +++ b/test/tests/p5.Amplitude.js @@ -1,26 +1,26 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Amplitude', function() { + describe('p5.Amplitude', function () { this.timeout(1000); var sf, amp; - it('can be created', function() { + it('can be created', function () { amp = new p5.Amplitude(); }); - after(function(done) { - expect( amp.getLevel() ).to.not.equal(1.0); + after(function (done) { + expect(amp.getLevel()).to.not.equal(1.0); osc.dispose(); sf.dispose(); done(); }); var osc, oAmp; - it('accepts oscillator input', function() { + it('accepts oscillator input', function () { osc = new p5.Oscillator('square'); osc.amp(1); osc.start(); @@ -29,42 +29,40 @@ define(['chai'], function(chai) { oAmp.setInput(osc); }); - it('gets oscillator level', function() { - setTimeout(function() { + it('gets oscillator level', function () { + setTimeout(function () { // console.log( 'unnormalized: ' + oAmp.getLevel() ); - expect( oAmp.getLevel() ).to.be.closeTo(0.55, 0.25); + expect(oAmp.getLevel()).to.be.closeTo(0.55, 0.25); }, 100); }); - it('gets normalized osc level', function(done) { - setTimeout(function() { + it('gets normalized osc level', function (done) { + setTimeout(function () { oAmp.toggleNormalize(true); // console.log( 'normalized: ' + oAmp.getLevel() ); - expect( oAmp.getLevel() ).to.be.closeTo(1.0, 0.4); + expect(oAmp.getLevel()).to.be.closeTo(1.0, 0.4); done(); }, 200); }); - - it('loop a SoundFile with params, disconnected from master, setInput()', function(done) { + it('loop a SoundFile with params, disconnected from master, setInput()', function (done) { p5.prototype.soundFormats('ogg', 'mp3'); - sf = p5.prototype.loadSound('./testAudio/drum', function() { + sf = p5.prototype.loadSound('./testAudio/drum', function () { sf.disconnect(); - sf.loop(1,1,0.0, 0.05); + sf.loop(1, 1, 0.0, 0.05); sf.connect(amp); - setTimeout(function() { + setTimeout(function () { done(); }, 100); }); }); - it('stop getting level', function(done) { + it('stop getting level', function (done) { sf.stop(); - setTimeout(function() { + setTimeout(function () { // console.log( amp.getLevel() ); done(); }, 10); }); - }); }); diff --git a/test/tests/p5.AudioIn.js b/test/tests/p5.AudioIn.js index 43e1dde2..7a3ff02f 100644 --- a/test/tests/p5.AudioIn.js +++ b/test/tests/p5.AudioIn.js @@ -1,41 +1,39 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.AudioIn', function() { - it('can be created and disposed', function() { + describe('p5.AudioIn', function () { + it('can be created and disposed', function () { var mic = new p5.AudioIn(); mic.dispose(); }); - it('can be started and stopped', function() { + it('can be started and stopped', function () { var mic = new p5.AudioIn(); - mic.start(function() { + mic.start(function () { mic.stop(); }); }); - it('can get sources', function(done) { + it('can get sources', function (done) { var mic = new p5.AudioIn(); - mic.getSources().then(function(sources) { + mic.getSources().then(function (sources) { console.log(sources); expect(sources).to.be.an('array'); done(); }); }); - it('can set source', function(done) { + it('can set source', function (done) { var mic = new p5.AudioIn(); expect(mic.currentSource).to.be.null; - return mic.getSources().then(function() { + return mic.getSources().then(function () { mic.setSource(0); expect(mic.currentSource).to.equal(0); done(); }); }); }); - }); diff --git a/test/tests/p5.AudioVoice.js b/test/tests/p5.AudioVoice.js index 292562e6..543822c4 100644 --- a/test/tests/p5.AudioVoice.js +++ b/test/tests/p5.AudioVoice.js @@ -1,14 +1,12 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.AudioVoice', function() { - - it('can be created and disposed', function() { + describe('p5.AudioVoice', function () { + it('can be created and disposed', function () { var av = new p5.AudioVoice(); av.dispose(); }); }); - }); diff --git a/test/tests/p5.Compressor.js b/test/tests/p5.Compressor.js index fcfaf9c0..49d97462 100644 --- a/test/tests/p5.Compressor.js +++ b/test/tests/p5.Compressor.js @@ -1,21 +1,20 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Compressor', function() { - - it('can be created and disposed', function() { + describe('p5.Compressor', function () { + it('can be created and disposed', function () { var compressor = new p5.Compressor(); compressor.dispose(); }); - it('wet dry value can be changed', function() { + it('wet dry value can be changed', function () { var compressor = new p5.Compressor(); expect(compressor.drywet(0.5)).to.equal(0.5); }); - it('can set params', function() { + it('can set params', function () { var compressor = new p5.Compressor(); compressor.set(0.5, 20, 15, -50, 0.75); expect(compressor.attack()).to.equal(0.5); @@ -24,6 +23,5 @@ define(['chai'], function(chai) { expect(compressor.threshold()).to.equal(-50); expect(compressor.release()).to.equal(0.75); }); - }); }); diff --git a/test/tests/p5.Delay.js b/test/tests/p5.Delay.js index 12af0468..af20e564 100644 --- a/test/tests/p5.Delay.js +++ b/test/tests/p5.Delay.js @@ -1,31 +1,28 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Delay', function() { - - it('can be created and disposed', function() { + describe('p5.Delay', function () { + it('can be created and disposed', function () { var delay = new p5.Delay(); delay.dispose(); }); - it('has initial feedback value of 0.5', function() { + it('has initial feedback value of 0.5', function () { var delay = new p5.Delay(); expect(delay.feedback()).to.equal(0.5); }); - it('can set feedback', function() { + it('can set feedback', function () { var delay = new p5.Delay(); delay.feedback(0.7); expect(delay.feedback()).to.be.closeTo(0.7, 0.001); }); - it('drywet value can be changed', function() { + it('drywet value can be changed', function () { var effect = new p5.Effect(); expect(effect.drywet(0.5)).to.equal(0.5); }); - }); }); diff --git a/test/tests/p5.Distortion.js b/test/tests/p5.Distortion.js index 783ddd5f..85a2c2ee 100644 --- a/test/tests/p5.Distortion.js +++ b/test/tests/p5.Distortion.js @@ -1,19 +1,19 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Distortion', function() { + describe('p5.Distortion', function () { this.timeout(1000); var dist = new p5.Distortion(); - it('can be created and disposed', function() { + it('can be created and disposed', function () { var d = new p5.Distortion(); d.dispose(); }); - it('can set the amount and oversample', function() { + it('can set the amount and oversample', function () { var initialAmt = dist.getAmount(); var initialOS = dist.getOversample(); dist.set(1000, '4x'); diff --git a/test/tests/p5.EQ.js b/test/tests/p5.EQ.js index 6a0c3d2b..fde062c1 100644 --- a/test/tests/p5.EQ.js +++ b/test/tests/p5.EQ.js @@ -1,12 +1,10 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.EQ', function() { - - it('can be created and disposed', function() { + describe('p5.EQ', function () { + it('can be created and disposed', function () { var origSoundArrayLength = p5.soundOut.soundArray.length; var eq = new p5.EQ(); expect(p5.soundOut.soundArray.length).to.not.equal(origSoundArrayLength); @@ -17,7 +15,7 @@ define(['chai'], function(chai) { expect(eq.bands).to.equal(undefined); }); - it('can be only be created with size 3 or 8', function() { + it('can be only be created with size 3 or 8', function () { var eq = new p5.EQ(); expect(eq.bands.length).to.equal(3); eq.dispose(); @@ -32,7 +30,7 @@ define(['chai'], function(chai) { eq.dispose(); }); - it('a band can be toggled on and off', function() { + it('a band can be toggled on and off', function () { var eq = new p5.EQ(8); expect(eq.bands[2].biquad.type).to.equal('peaking'); eq.bands[2].toggle(); @@ -41,14 +39,14 @@ define(['chai'], function(chai) { expect(eq.bands[2].biquad.type).to.equal('peaking'); }); - it('a bands gain value can be changed', function() { + it('a bands gain value can be changed', function () { var eq = new p5.EQ(8); expect(eq.bands[2].gain()).to.equal(0); eq.bands[2].gain(30); expect(eq.bands[2].gain()).to.equal(30); }); - it('a bands freq value can be changed', function() { + it('a bands freq value can be changed', function () { var eq = new p5.EQ(8); expect(eq.bands[0].freq()).to.equal(100); eq.bands[0].freq(200); @@ -56,14 +54,14 @@ define(['chai'], function(chai) { expect(eq.bands[0].freq()).to.equal(200); }); - it('a bands type can be changed', function() { + it('a bands type can be changed', function () { var eq = new p5.EQ(); expect(eq.bands[2]._untoggledType).to.equal('peaking'); eq.bands[2].setType('highshelf'); expect(eq.bands[2]._untoggledType).to.equal('highshelf'); }); - it('drywet value can be changed', function() { + it('drywet value can be changed', function () { var eq = new p5.EQ(); expect(eq.drywet(0.5)).to.equal(0.5); }); diff --git a/test/tests/p5.Effect.js b/test/tests/p5.Effect.js index d5c10bff..1ce6fb2a 100644 --- a/test/tests/p5.Effect.js +++ b/test/tests/p5.Effect.js @@ -1,12 +1,10 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Effect', function() { - - it('can be created and disposed', function() { + describe('p5.Effect', function () { + it('can be created and disposed', function () { var effect = new p5.Effect(); effect.dispose(); expect(effect.wet).to.equal(undefined); @@ -15,18 +13,18 @@ define(['chai'], function(chai) { expect(effect.output).to.equal(undefined); }); - it('drywet value can be changed', function() { + it('drywet value can be changed', function () { var effect = new p5.Effect(); expect(effect.drywet(0.5)).to.equal(0.5); }); - it('drywet value can be used as getter and setter', function() { + it('drywet value can be used as getter and setter', function () { var effect = new p5.Effect(); expect(effect.drywet(0.5)).to.equal(0.5); expect(effect.drywet()).to.equal(0.5); }); - it('effects can be chained together', function() { + it('effects can be chained together', function () { var filter = new p5.Filter(); var delay = new p5.Delay(); var reverb = new p5.Reverb(); diff --git a/test/tests/p5.FFT.js b/test/tests/p5.FFT.js index c9c7d210..ef7a1b85 100644 --- a/test/tests/p5.FFT.js +++ b/test/tests/p5.FFT.js @@ -1,36 +1,36 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.FFT', function() { + describe('p5.FFT', function () { var fft; - beforeEach(function() { + beforeEach(function () { fft = new p5.FFT(); }); - afterEach(function() { + afterEach(function () { fft.dispose(); }); - it('has default bins of 1024', function() { + it('has default bins of 1024', function () { expect(fft.bins).to.equal(1024); }); - it('has default smoothing of 0.8', function() { + it('has default smoothing of 0.8', function () { expect(fft.smooth()).to.equal(0.8); expect(fft.smoothing).to.equal(0.8); }); - it('accepts smoothing and bins as args', function() { + it('accepts smoothing and bins as args', function () { fft.dispose(); fft = new p5.FFT(0, 128); expect(fft.smoothing).to.equal(0); expect(fft.bins).to.equal(128); }); - it('can set smoothing to zero', function() { + it('can set smoothing to zero', function () { fft.smooth(0); expect(fft.smoothing).to.equal(0); expect(fft.smooth()).to.equal(0); @@ -39,12 +39,12 @@ define(['chai'], function(chai) { expect(fft.smooth()).to.equal(0.9); }); - it('handles smoothing values out of range', function() { + it('handles smoothing values out of range', function () { expect(fft.smooth()).to.equal(0.8); try { fft.smooth(-1); expect.fail(); - } catch(e) { + } catch (e) { expect(e).to.be.an.instanceof(Error); } expect(fft.smoothing).to.equal(0.8); @@ -52,7 +52,7 @@ define(['chai'], function(chai) { try { fft.smooth('some bad param'); expect.fail(); - } catch(e) { + } catch (e) { expect(e).to.be.an.instanceof(Error); } expect(fft.smoothing).to.equal(0.8); diff --git a/test/tests/p5.Filter.js b/test/tests/p5.Filter.js index 0390ba5d..6ba78aba 100644 --- a/test/tests/p5.Filter.js +++ b/test/tests/p5.Filter.js @@ -1,27 +1,23 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Filter', function() { - - it('can be created and disposed', function() { + describe('p5.Filter', function () { + it('can be created and disposed', function () { var filter = new p5.Filter(); filter.dispose(); }); - it('has initial drywet value of 0.5', function() { + it('has initial drywet value of 0.5', function () { var filter = new p5.Filter(); expect(filter.drywet(0.5)).to.equal(0.5); }); - it('audio can be processed', function() { + it('audio can be processed', function () { var filter = new p5.Filter(); var sound = new p5.SoundFile('./testAudio/drum.mp3'); filter.process(sound, 500, 5); }); - - }); }); diff --git a/test/tests/p5.MonoSynth.js b/test/tests/p5.MonoSynth.js index 79eb5cad..89083537 100644 --- a/test/tests/p5.MonoSynth.js +++ b/test/tests/p5.MonoSynth.js @@ -1,27 +1,24 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.MonoSynth', function() { - - it('can be created and disposed', function() { + describe('p5.MonoSynth', function () { + it('can be created and disposed', function () { var monoSynth = new p5.MonoSynth(); monoSynth.dispose(); }); - it('can play a note string', function(done) { + it('can play a note string', function (done) { var monoSynth = new p5.MonoSynth(); monoSynth.play('A2'); // wait for scheduled value to complete - setTimeout(function() { + setTimeout(function () { expect(monoSynth.oscillator.freq().value).to.equal(110); monoSynth.dispose(); done(); }, 1); }); }); - }); diff --git a/test/tests/p5.Oscillator.js b/test/tests/p5.Oscillator.js index da2c92f3..2834e52c 100644 --- a/test/tests/p5.Oscillator.js +++ b/test/tests/p5.Oscillator.js @@ -1,49 +1,48 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Oscillator', function() { + describe('p5.Oscillator', function () { this.timeout(1000); var osc = new p5.Oscillator(); var amp = new p5.Amplitude(); - after(function() { + after(function () { osc.dispose(); }); - it('can be created and disposed', function() { + it('can be created and disposed', function () { var o = new p5.Oscillator(); o.dispose(); }); - it('starts and stops', function(done) { + it('starts and stops', function (done) { expect(osc.started).to.equal(false); osc.start(); expect(osc.started).to.equal(true); - setTimeout(function() { + setTimeout(function () { osc.stop(); done(); }, 100); }); - it('can be scheduled to stop', function(done) { + it('can be scheduled to stop', function (done) { osc.stop(); expect(osc.started).to.equal(false); osc.start(); expect(osc.started).to.equal(true); osc.stop(0.05); - setTimeout(function() { + setTimeout(function () { expect(osc.started).to.equal(false); done(); }, 55); }); - it('wont start again before stopping', function(done) { + it('wont start again before stopping', function (done) { expect(osc.started).to.equal(false); - setTimeout(function() { + setTimeout(function () { osc.amp(1); osc.start(); osc.stop(); @@ -52,7 +51,7 @@ define(['chai'], function(chai) { osc.start(); amp.setInput(osc); amp.getLevel(); - setTimeout(function() { + setTimeout(function () { expect(osc.started).to.equal(true); expect(amp.volMax).not.equal(0.0); osc.stop(); @@ -74,11 +73,11 @@ define(['chai'], function(chai) { // }, 15); // }); - it('can start in the future', function(done) { + it('can start in the future', function (done) { expect(osc.started).to.equal(false); osc.start(0.05); // expect( amp.getLevel() ).to.be.closeTo(0.0, 0.5); - setTimeout(function() { + setTimeout(function () { expect(osc.started).to.equal(true); // expect( amp.getLevel ).to.not.equal(0.0); osc.stop(); @@ -86,6 +85,5 @@ define(['chai'], function(chai) { done(); }, 55); }); - }); }); diff --git a/test/tests/p5.PolySynth.js b/test/tests/p5.PolySynth.js index 7ccd2b81..7dd035ca 100644 --- a/test/tests/p5.PolySynth.js +++ b/test/tests/p5.PolySynth.js @@ -1,26 +1,27 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.PolySynth', function() { + describe('p5.PolySynth', function () { var audioContext = p5.prototype.getAudioContext(); - it('can be created and disposed', function() { + it('can be created and disposed', function () { var polySynth = new p5.PolySynth(); polySynth.dispose(); }); - it('keeps track of the number of voicesInUse', function() { + it('keeps track of the number of voicesInUse', function () { var polySynth = new p5.PolySynth(); var noteDuration = 0.01; var noteTriggerTime = audioContext.currentTime; - var noteActiveTime = noteTriggerTime + noteDuration/2; + var noteActiveTime = noteTriggerTime + noteDuration / 2; var noteDoneTime = noteTriggerTime + noteDuration; - expect(polySynth._voicesInUse.getValueAtTime(noteTriggerTime)).to.equal(0); + expect(polySynth._voicesInUse.getValueAtTime(noteTriggerTime)).to.equal( + 0 + ); polySynth.play('A2', 0, 0, noteDuration); expect(polySynth._voicesInUse.getValueAtTime(noteActiveTime)).to.equal(1); @@ -34,5 +35,4 @@ define(['chai'], function(chai) { polySynth.dispose(); }); }); - }); diff --git a/test/tests/p5.Reverb.js b/test/tests/p5.Reverb.js index 8446a2d4..8b5f766b 100644 --- a/test/tests/p5.Reverb.js +++ b/test/tests/p5.Reverb.js @@ -1,17 +1,15 @@ 'use strict'; -define(['chai'], function(chai) { - +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.Reverb', function() { - - it('can be created and disposed', function() { + describe('p5.Reverb', function () { + it('can be created and disposed', function () { var reverb = new p5.Reverb(); reverb.dispose(); }); - it('default parmams-> seconds:3, decay: 2, reverse: false', function() { + it('default parmams-> seconds:3, decay: 2, reverse: false', function () { var reverb = new p5.Reverb(); expect(reverb._seconds).to.equal(3); @@ -19,19 +17,18 @@ define(['chai'], function(chai) { expect(reverb._reverse).to.equal(false); }); - it('can set seconds, decayRate, reverse', function() { + it('can set seconds, decayRate, reverse', function () { var reverb = new p5.Reverb(); - reverb.set(5,6,true); + reverb.set(5, 6, true); expect(reverb._seconds).to.equal(5); expect(reverb._decay).to.equal(6); expect(reverb._reverse).to.equal(true); }); - it('drywet value can be changed', function() { + it('drywet value can be changed', function () { var effect = new p5.Effect(); expect(effect.drywet(0.5)).to.equal(0.5); }); - }); }); diff --git a/test/tests/p5.SoundFile.js b/test/tests/p5.SoundFile.js index aea38d3f..1b7c1400 100644 --- a/test/tests/p5.SoundFile.js +++ b/test/tests/p5.SoundFile.js @@ -1,120 +1,119 @@ 'use strict'; -define(['chai'], function(chai) { +define(['chai'], function (chai) { var expect = chai.expect; - describe('p5.SoundFile', function() { + describe('p5.SoundFile', function () { this.timeout(1000); var sf; var a = new p5.Amplitude(); - after(function(done) { + after(function (done) { sf.dispose(); done(); }); - it('loads a file with soundFormats', function(done) { + it('loads a file with soundFormats', function (done) { p5.prototype.soundFormats('ogg', 'mp3'); - sf = p5.prototype.loadSound('./testAudio/drum', function() { + sf = p5.prototype.loadSound('./testAudio/drum', function () { done(); }); }); - it('can be created and disposed', function() { - var p = new p5.SoundFile('./testAudio/drum', function() { + it('can be created and disposed', function () { + var p = new p5.SoundFile('./testAudio/drum', function () { p.dispose(); }); }); - it('plays a file', function() { + it('plays a file', function () { sf.play(); - expect( sf.isPlaying() ).to.equal(true); + expect(sf.isPlaying()).to.equal(true); }); - it('stops playing a file', function() { + it('stops playing a file', function () { sf.stop(); - expect( sf.isPlaying() ).to.equal(false); + expect(sf.isPlaying()).to.equal(false); }); - it('pauses a file', function() { + it('pauses a file', function () { sf.play(); sf.pause(); - expect( sf.isPlaying() ).to.equal(false); - expect( sf.isPaused() ).to.equal(true); + expect(sf.isPlaying()).to.equal(false); + expect(sf.isPaused()).to.equal(true); }); - it('has a duration', function() { - expect( sf.duration() ).to.be.closeTo(1.0, 0.01); + it('has a duration', function () { + expect(sf.duration()).to.be.closeTo(1.0, 0.01); }); - it('can change playback rate', function() { - sf.rate(.5); + it('can change playback rate', function () { + sf.rate(0.5); expect(sf.playbackRate).to.equal(0.5); }); - it('can set panning', function() { + it('can set panning', function () { sf.pan(-1); expect(sf.panPosition).to.equal(-1); }); - it('can play again and keep currentTime', function() { + it('can play again and keep currentTime', function () { sf.play(); - expect( sf.isPaused() ).to.equal(false); - expect( sf.isPlaying() ).to.equal(true); + expect(sf.isPaused()).to.equal(false); + expect(sf.isPlaying()).to.equal(true); - setTimeout(function() { - expect( sf.currentTime() ).not.equal(0.0); + setTimeout(function () { + expect(sf.currentTime()).not.equal(0.0); }, 100); }); var peaks, firstPeak; - it('can get peaks', function() { + it('can get peaks', function () { peaks = sf.getPeaks(sf.buffer.length); expect(peaks.length).to.equal(sf.buffer.length); firstPeak = peaks[0]; }); - it('can reverse buffer with playbackRate', function() { + it('can reverse buffer with playbackRate', function () { sf.rate(-1); var reversePeaks = sf.getPeaks(sf.buffer.length); expect(reversePeaks[reversePeaks.length - 1]).to.equal(firstPeak); }); - it('can revert buffer to normal with positive playbackRate', function() { + it('can revert buffer to normal with positive playbackRate', function () { sf.rate(1); var revertPeaks = sf.getPeaks(sf.buffer.length); expect(revertPeaks[0]).to.equal(firstPeak); }); - it('can handle multiple restarts', function() { - expect( sf.isPlaying() ).to.equal(true); + it('can handle multiple restarts', function () { + expect(sf.isPlaying()).to.equal(true); sf.play(); sf.play(); sf.stop(); sf.stop(); - expect( sf.isPlaying() ).to.equal(false); + expect(sf.isPlaying()).to.equal(false); sf.play(); a.setInput(sf); - expect( sf.isPlaying() ).to.equal(true); + expect(sf.isPlaying()).to.equal(true); }); - it('can make noise', function(done) { - setTimeout(function() { + it('can make noise', function (done) { + setTimeout(function () { expect(a.getLevel()).to.not.equal(0.0); done(); }, 50); }); - it('can set volume', function(done) { + it('can set volume', function (done) { sf.stop(); sf.play(); sf.setVolume(0); - setTimeout(function() { - expect( a.getLevel() ).to.be.closeTo(0.0, 0.3); + setTimeout(function () { + expect(a.getLevel()).to.be.closeTo(0.0, 0.3); done(); }, 100); }); - }); }); diff --git a/test/tests/p5.SoundRecorder.js b/test/tests/p5.SoundRecorder.js index 8eb18485..3cf3ffa6 100644 --- a/test/tests/p5.SoundRecorder.js +++ b/test/tests/p5.SoundRecorder.js @@ -1,14 +1,14 @@ 'use strict'; -define(['chai', 'sinon'], function(chai, sinon) { +define(['chai', 'sinon'], function (chai, sinon) { var expect = chai.expect; - describe('p5.SoundRecorder', function() { + describe('p5.SoundRecorder', function () { var recorder; var inputSoundFile; var writeFileSub; - before(function(done) { + before(function (done) { this.timeout(10000); writeFileSub = sinon.stub(p5.prototype, 'writeFile'); @@ -18,42 +18,46 @@ define(['chai', 'sinon'], function(chai, sinon) { // request microphone access and throw an error if permission is denied var tempMic = new p5.AudioIn(); - tempMic.start(function() { - tempMic.dispose(); - done(); - }, function() { - tempMic.dispose(); - done(new Error('Microphone access denied')); - }); + tempMic.start( + function () { + tempMic.dispose(); + done(); + }, + function () { + tempMic.dispose(); + done(new Error('Microphone access denied')); + } + ); }); - after(function() { + after(function () { inputSoundFile.dispose(); writeFileSub.restore(); }); - beforeEach(function() { + beforeEach(function () { recorder = new p5.SoundRecorder(); inputSoundFile.disconnect(); inputSoundFile.stop(); writeFileSub.reset(); }); - afterEach(function() { + afterEach(function () { recorder.dispose(); }); - it('can record input from a microphone', function(done) { + it('can record input from a microphone', function (done) { // this is the shortest possible recording duration - var recordingDuration = recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; + var recordingDuration = + recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; // need to enable master volume to test recording from the microphone p5.prototype.masterVolume(1); var mic = new p5.AudioIn(); - mic.start(function() { + mic.start(function () { var outputSoundFile = new p5.SoundFile(); - recorder.record(outputSoundFile, recordingDuration, function() { + recorder.record(outputSoundFile, recordingDuration, function () { expect(outputSoundFile.duration()).to.eq(recordingDuration); var outputChannel = outputSoundFile.buffer.getChannelData(0); @@ -67,10 +71,11 @@ define(['chai', 'sinon'], function(chai, sinon) { }); }); - it('can record input from a sound file', function(done) { + it('can record input from a sound file', function (done) { var sampleIndex = 0; // this is the shortest possible recording duration - var recordingDuration = recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; + var recordingDuration = + recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; var inputChannel = inputSoundFile.buffer.getChannelData(0); // input SoundFile should contain all 1s expect(inputChannel[sampleIndex]).to.eq(1); @@ -78,7 +83,7 @@ define(['chai', 'sinon'], function(chai, sinon) { var outputSoundFile = new p5.SoundFile(); inputSoundFile.loop(); recorder.setInput(inputSoundFile); - recorder.record(outputSoundFile, recordingDuration, function() { + recorder.record(outputSoundFile, recordingDuration, function () { expect(outputSoundFile.duration()).to.eq(recordingDuration); var outputChannel = outputSoundFile.buffer.getChannelData(0); @@ -89,9 +94,10 @@ define(['chai', 'sinon'], function(chai, sinon) { }); }); - it('can record the master output of a sketch', function(done) { + it('can record the master output of a sketch', function (done) { // this is the shortest possible recording duration - var recordingDuration = recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; + var recordingDuration = + recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; var inputChannel = inputSoundFile.buffer.getChannelData(0); // input SoundFile should contain all 1s expect(inputChannel[0]).to.eq(1); @@ -103,7 +109,7 @@ define(['chai', 'sinon'], function(chai, sinon) { inputSoundFile.connect(); inputSoundFile.loop(); recorder.setInput(); - recorder.record(outputSoundFile, recordingDuration, function() { + recorder.record(outputSoundFile, recordingDuration, function () { expect(outputSoundFile.duration()).to.eq(recordingDuration); var outputChannel = outputSoundFile.buffer.getChannelData(0); @@ -115,14 +121,15 @@ define(['chai', 'sinon'], function(chai, sinon) { }); }); - it('can save a recorded buffer to a .wav file', function(done) { + it('can save a recorded buffer to a .wav file', function (done) { // this is the shortest possible recording duration - var recordingDuration = recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; + var recordingDuration = + recorder.bufferSize / p5.soundOut.audiocontext.sampleRate; var outputSoundFile = new p5.SoundFile(); inputSoundFile.play(); recorder.setInput(inputSoundFile); - recorder.record(outputSoundFile, recordingDuration, function() { + recorder.record(outputSoundFile, recordingDuration, function () { expect(outputSoundFile.duration()).to.eq(recordingDuration); p5.prototype.saveSound(outputSoundFile, 'test.wav'); From 059610075ff86b63c857efe7a391d0a4b1223b71 Mon Sep 17 00:00:00 2001 From: Jason Sigal Date: Thu, 14 May 2020 00:44:02 -0400 Subject: [PATCH 2/9] manually fix what eslint could not auto fix --- src/compressor.js | 2 -- src/effect.js | 20 ++++------- src/envelope.js | 3 +- src/errorHandler.js | 3 +- src/fft.js | 30 ++++++++-------- src/gain.js | 4 +-- src/helpers.js | 18 +++++----- src/master.js | 4 +-- src/metro.js | 3 +- src/monosynth.js | 6 ++-- src/noise.js | 70 ++++++++++++++++++------------------- src/oscillator.js | 18 +++------- src/panner.js | 2 +- src/panner3d.js | 1 - src/polysynth.js | 20 ++++++----- src/pulse.js | 4 +-- src/reverb.js | 4 +-- src/soundLoop.js | 2 +- test/tests/p5.Amplitude.js | 3 +- test/tests/p5.AudioVoice.js | 2 -- 20 files changed, 95 insertions(+), 124 deletions(-) diff --git a/src/compressor.js b/src/compressor.js index 589920b3..50fae6fa 100644 --- a/src/compressor.js +++ b/src/compressor.js @@ -1,9 +1,7 @@ define(function (require) { 'use strict'; - var p5sound = require('master'); var Effect = require('effect'); - var CustomError = require('errorHandler'); /** * Compressor is an audio effect class that performs dynamics compression diff --git a/src/effect.js b/src/effect.js index 362a114b..3e1f34c7 100644 --- a/src/effect.js +++ b/src/effect.js @@ -66,20 +66,14 @@ define(function (require) { * @param {Number} [rampTime] create a fade that lasts until rampTime * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds */ - p5.Effect.prototype.amp = function (vol, rampTime, tFromNow) { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; - var now = p5sound.audiocontext.currentTime; - var currentVol = this.output.gain.value; + p5.Effect.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) { + const now = p5sound.audiocontext.currentTime; + const startTime = now + tFromNow; + const endTime = startTime + rampTime + 0.001; + const currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(now); - this.output.gain.linearRampToValueAtTime( - currentVol, - now + tFromNow + 0.001 - ); - this.output.gain.linearRampToValueAtTime( - vol, - now + tFromNow + rampTime + 0.001 - ); + this.output.gain.linearRampToValueAtTime(currentVol, startTime + 0.001); + this.output.gain.linearRampToValueAtTime(vol, endTime); }; /** diff --git a/src/envelope.js b/src/envelope.js index 4310a9d4..6509f6bd 100644 --- a/src/envelope.js +++ b/src/envelope.js @@ -455,7 +455,6 @@ define(function (require) { */ p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) { var tFromNow = secondsFromNow || 0; - var susTime = susTime || 0; if (unit) { if (this.connection !== unit) { @@ -465,7 +464,7 @@ define(function (require) { this.triggerAttack(unit, tFromNow); - this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime); + this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + ~~susTime); }; /** diff --git a/src/errorHandler.js b/src/errorHandler.js index 3f00a700..a0bf6582 100644 --- a/src/errorHandler.js +++ b/src/errorHandler.js @@ -30,8 +30,7 @@ define(function () { err.failedPath = failedPath; // only print the part of the stack trace that refers to the user code: - var splitStack = tempStack.split('\n'); - splitStack = splitStack.filter(function (ln) { + splitStack = tempStack.split('\n').filter(function (ln) { return !ln.match(/(p5.|native code|globalInit)/g); }); err.stack = splitStack.join('\n'); diff --git a/src/fft.js b/src/fft.js index 0276008b..4f514490 100644 --- a/src/fft.js +++ b/src/fft.js @@ -173,7 +173,8 @@ define(function (require) { * */ p5.FFT.prototype.waveform = function () { - var bins, mode, normalArray; + var bins, mode; + var normalArray = new Array(); for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === 'number') { @@ -193,7 +194,6 @@ define(function (require) { } else { timeToInt(this, this.timeDomain); this.analyser.getByteTimeDomainData(this.timeDomain); - var normalArray = new Array(); for (var j = 0; j < this.timeDomain.length; j++) { var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1); normalArray.push(scaled); @@ -512,8 +512,8 @@ define(function (require) { * @param {Number} N Number of returned frequency groups * @return {Array} linearAverages Array of average amplitude values for each group */ - p5.FFT.prototype.linAverages = function (N) { - var N = N || 16; // This prevents undefined, null or 0 values of N + p5.FFT.prototype.linAverages = function (_N) { + var N = _N || 16; // This prevents undefined, null or 0 values of N var spectrum = this.freqDomain; var spectrumLength = spectrum.length; @@ -595,9 +595,9 @@ define(function (require) { * @param {Number} fCtr0 Minimum central frequency for the lowest band * @return {Array} octaveBands Array of octave band objects with their bounds */ - p5.FFT.prototype.getOctaveBands = function (N, fCtr0) { - var N = N || 3; // Default to 1/3 Octave Bands - var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz + p5.FFT.prototype.getOctaveBands = function (_N, _fCtr0) { + var N = _N || 3; // Default to 1/3 Octave Bands + var fCtr0 = _fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz var octaveBands = []; var lastFrequencyBand = { @@ -622,24 +622,24 @@ define(function (require) { }; // helper methods to convert type from float (dB) to int (0-255) - var freqToFloat = function (fft) { + function freqToFloat(fft) { if (fft.freqDomain instanceof Float32Array === false) { fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount); } - }; - var freqToInt = function (fft) { + } + function freqToInt(fft) { if (fft.freqDomain instanceof Uint8Array === false) { fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount); } - }; - var timeToFloat = function (fft) { + } + function timeToFloat(fft) { if (fft.timeDomain instanceof Float32Array === false) { fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount); } - }; - var timeToInt = function (fft) { + } + function timeToInt(fft) { if (fft.timeDomain instanceof Uint8Array === false) { fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount); } - }; + } }); diff --git a/src/gain.js b/src/gain.js index ce1698b5..89a1063c 100644 --- a/src/gain.js +++ b/src/gain.js @@ -132,9 +132,7 @@ define(function (require) { * @param {Number} [timeFromNow] schedule this event to happen * seconds from now */ - p5.Gain.prototype.amp = function (vol, rampTime, tFromNow) { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; + p5.Gain.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) { var now = p5sound.audiocontext.currentTime; var currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(now); diff --git a/src/helpers.js b/src/helpers.js index 608f91b5..451135f6 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -168,20 +168,18 @@ define(function (require) { var extTest = path.split('.').pop(); // if an extension is provided... if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(extTest) > -1) { - if (p5.prototype.isFileSupported(extTest)) { - path = path; - } else { + if (!p5.prototype.isFileSupported(extTest)) { var pathSplit = path.split('.'); var pathCore = pathSplit[pathSplit.length - 1]; - for (var i = 0; i < p5sound.extensions.length; i++) { - var extension = p5sound.extensions[i]; - var supported = p5.prototype.isFileSupported(extension); + for (let i = 0; i < p5sound.extensions.length; i++) { + const extension = p5sound.extensions[i]; + const supported = p5.prototype.isFileSupported(extension); if (supported) { pathCore = ''; if (pathSplit.length === 2) { pathCore += pathSplit[0]; } - for (var i = 1; i <= pathSplit.length - 2; i++) { + for (let i = 1; i <= pathSplit.length - 2; i++) { var p = pathSplit[i]; pathCore += '.' + p; } @@ -194,9 +192,9 @@ define(function (require) { } // if no extension is provided... else { - for (var i = 0; i < p5sound.extensions.length; i++) { - var extension = p5sound.extensions[i]; - var supported = p5.prototype.isFileSupported(extension); + for (let i = 0; i < p5sound.extensions.length; i++) { + const extension = p5sound.extensions[i]; + const supported = p5.prototype.isFileSupported(extension); if (supported) { path = path + '.' + extension; break; diff --git a/src/master.js b/src/master.js index d66c0c10..6b6a3ecb 100644 --- a/src/master.js +++ b/src/master.js @@ -81,10 +81,8 @@ define(['audiocontext'], function (audiocontext) { * @param {Number} [timeFromNow] Schedule this event to happen at * t seconds in the future */ - p5.prototype.masterVolume = function (vol, rampTime, tFromNow) { + p5.prototype.masterVolume = function (vol, rampTime = 0, tFromNow = 0) { if (typeof vol === 'number') { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; var currentVol = p5sound.output.gain.value; p5sound.output.gain.cancelScheduledValues(now + tFromNow); diff --git a/src/metro.js b/src/metro.js index 18b31d9b..c291edc4 100644 --- a/src/metro.js +++ b/src/metro.js @@ -52,12 +52,11 @@ define(function (require) { } }; - p5.Metro.prototype.setBPM = function (bpm, rampTime) { + p5.Metro.prototype.setBPM = function (bpm, rampTime = 0) { var beatTime = 60 / (bpm * this.tatums); var now = p5sound.audiocontext.currentTime; this.tatumTime = beatTime; - var rampTime = rampTime || 0; this.clock.frequency.setValueAtTime(this.clock.frequency.value, now); this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime); this.bpm = bpm; diff --git a/src/monosynth.js b/src/monosynth.js index 13f25630..505207b3 100644 --- a/src/monosynth.js +++ b/src/monosynth.js @@ -168,9 +168,8 @@ define(function (require) { p5.MonoSynth.prototype.triggerAttack = function ( note, velocity, - secondsFromNow + secondsFromNow = 0 ) { - var secondsFromNow = ~~secondsFromNow; var freq = noteToFreq(note); var vel = velocity || 0.1; this.oscillator.freq(freq, 0, secondsFromNow); @@ -208,8 +207,7 @@ define(function (require) { * } * */ - p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) { - var secondsFromNow = secondsFromNow || 0; + p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow = 0) { this.env.ramp(this.output.gain, secondsFromNow, 0); }; diff --git a/src/noise.js b/src/noise.js index c0bf00eb..5c1eeae7 100644 --- a/src/noise.js +++ b/src/noise.js @@ -3,36 +3,8 @@ define(function (require) { var p5sound = require('master'); - /** - * Noise is a type of oscillator that generates a buffer with random values. - * - * @class p5.Noise - * @extends p5.Oscillator - * @constructor - * @param {String} type Type of noise can be 'white' (default), - * 'brown' or 'pink'. - */ - p5.Noise = function (type) { - var assignType; - p5.Oscillator.call(this); - delete this.f; - delete this.freq; - delete this.oscillator; - - if (type === 'brown') { - assignType = _brownNoise; - } else if (type === 'pink') { - assignType = _pinkNoise; - } else { - assignType = _whiteNoise; - } - this.buffer = assignType; - }; - - p5.Noise.prototype = Object.create(p5.Oscillator.prototype); - // generate noise buffers - var _whiteNoise = (function () { + const _whiteNoiseBuffer = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var whiteBuffer = p5sound.audiocontext.createBuffer( 1, @@ -47,7 +19,7 @@ define(function (require) { return whiteBuffer; })(); - var _pinkNoise = (function () { + const _pinkNoiseBuffer = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var pinkBuffer = p5sound.audiocontext.createBuffer( 1, @@ -73,7 +45,7 @@ define(function (require) { return pinkBuffer; })(); - var _brownNoise = (function () { + const _brownNoiseBuffer = (function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var brownBuffer = p5sound.audiocontext.createBuffer( 1, @@ -92,6 +64,34 @@ define(function (require) { return brownBuffer; })(); + /** + * Noise is a type of oscillator that generates a buffer with random values. + * + * @class p5.Noise + * @extends p5.Oscillator + * @constructor + * @param {String} type Type of noise can be 'white' (default), + * 'brown' or 'pink'. + */ + p5.Noise = function (type) { + var assignType; + p5.Oscillator.call(this); + delete this.f; + delete this.freq; + delete this.oscillator; + + if (type === 'brown') { + assignType = _brownNoiseBuffer; + } else if (type === 'pink') { + assignType = _pinkNoiseBuffer; + } else { + assignType = _whiteNoiseBuffer; + } + this.buffer = assignType; + }; + + p5.Noise.prototype = Object.create(p5.Oscillator.prototype); + /** * Set type of noise to 'white', 'pink' or 'brown'. * White is the default. @@ -102,16 +102,16 @@ define(function (require) { p5.Noise.prototype.setType = function (type) { switch (type) { case 'white': - this.buffer = _whiteNoise; + this.buffer = _whiteNoiseBuffer; break; case 'pink': - this.buffer = _pinkNoise; + this.buffer = _pinkNoiseBuffer; break; case 'brown': - this.buffer = _brownNoise; + this.buffer = _brownNoiseBuffer; break; default: - this.buffer = _whiteNoise; + this.buffer = _whiteNoiseBuffer; } if (this.started) { var now = p5sound.audiocontext.currentTime; diff --git a/src/oscillator.js b/src/oscillator.js index 1d150240..9e6f2161 100644 --- a/src/oscillator.js +++ b/src/oscillator.js @@ -71,12 +71,12 @@ define(function (require) { */ p5.Oscillator = function (freq, type) { if (typeof freq === 'string') { - var f = type; + let f = type; type = freq; freq = f; } if (typeof type === 'number') { - var f = type; + let f = type; type = freq; freq = f; } @@ -197,15 +197,12 @@ define(function (require) { * this oscillator's * gain/amplitude/volume) */ - p5.Oscillator.prototype.amp = function (vol, rampTime, tFromNow) { - var self = this; + p5.Oscillator.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) { if (typeof vol === 'number') { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); } else if (vol) { - vol.connect(self.output.gain); + vol.connect(this.output.gain); } else { // return the Gain Node return this.output.gain; @@ -257,15 +254,10 @@ define(function (require) { * } * */ - p5.Oscillator.prototype.freq = function (val, rampTime, tFromNow) { + p5.Oscillator.prototype.freq = function (val, rampTime = 0, tFromNow = 0) { if (typeof val === 'number' && !isNaN(val)) { this.f = val; var now = p5sound.audiocontext.currentTime; - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; - var t = now + tFromNow + rampTime; - // var currentFreq = this.oscillator.frequency.value; - // this.oscillator.frequency.cancelScheduledValues(now); if (rampTime === 0) { this.oscillator.frequency.setValueAtTime(val, tFromNow + now); diff --git a/src/panner.js b/src/panner.js index cab602a1..74b2f9d7 100644 --- a/src/panner.js +++ b/src/panner.js @@ -83,7 +83,7 @@ define(function (require) { this.input.connect(this.left); this.input.connect(this.right); } else if (numChannels === 2) { - if (typeof (this.splitter === 'undefined')) { + if (typeof this.splitter === 'undefined') { this.splitter = ac.createChannelSplitter(2); } this.input.disconnect(); diff --git a/src/panner3d.js b/src/panner3d.js index a424c314..87022766 100644 --- a/src/panner3d.js +++ b/src/panner3d.js @@ -1,7 +1,6 @@ 'use strict'; define(function (require) { - var p5sound = require('master'); var Effect = require('effect'); /** diff --git a/src/polysynth.js b/src/polysynth.js index b7141dc9..7da5d5cb 100644 --- a/src/polysynth.js +++ b/src/polysynth.js @@ -154,9 +154,8 @@ define(function (require) { note, velocity, secondsFromNow, - susTime + susTime = 1 ) { - var susTime = susTime || 1; this.noteAttack(note, velocity, secondsFromNow); this.noteRelease(note, secondsFromNow + susTime); }; @@ -185,9 +184,15 @@ define(function (require) { * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) **/ - p5.PolySynth.prototype.noteADSR = function (note, a, d, s, r, timeFromNow) { + p5.PolySynth.prototype.noteADSR = function ( + note, + a, + d, + s, + r, + timeFromNow = 0 + ) { var now = p5sound.audiocontext.currentTime; - var timeFromNow = timeFromNow || 0; var t = now + timeFromNow; this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r); }; @@ -260,11 +265,8 @@ define(function (require) { p5.PolySynth.prototype.noteAttack = function ( _note, _velocity, - secondsFromNow + secondsFromNow = 0 ) { - //this value goes to the audiovoices which handle their own scheduling - var secondsFromNow = ~~secondsFromNow; - //this value is used by this._voicesInUse var acTime = p5sound.audiocontext.currentTime + secondsFromNow; @@ -318,6 +320,8 @@ define(function (require) { var maxRange = (1 / this._voicesInUse.getValueAtTime(acTime)) * 2; velocity = velocity > maxRange ? maxRange : velocity; } + + // use secondsFromNow because this method will add AudioContext currentTime this.audiovoices[currentVoice].triggerAttack( note, velocity, diff --git a/src/pulse.js b/src/pulse.js index bbfecd81..90777eb3 100644 --- a/src/pulse.js +++ b/src/pulse.js @@ -166,12 +166,10 @@ define(function (require) { } }; - p5.Pulse.prototype.freq = function (val, rampTime, tFromNow) { + p5.Pulse.prototype.freq = function (val, rampTime = 0, tFromNow = 0) { if (typeof val === 'number') { this.f = val; var now = p5sound.audiocontext.currentTime; - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var currentFreq = this.oscillator.frequency.value; this.oscillator.frequency.cancelScheduledValues(now); this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow); diff --git a/src/reverb.js b/src/reverb.js index 22dd759c..4dc21065 100644 --- a/src/reverb.js +++ b/src/reverb.js @@ -390,11 +390,11 @@ define(function (require) { * @private */ p5.Convolver.prototype._loadBuffer = function ( - path, + _path, callback, errorCallback ) { - var path = p5.prototype._checkFileFormats(path); + var path = p5.prototype._checkFileFormats(_path); var self = this; var errorTrace = new Error().stack; var ac = p5.prototype.getAudioContext(); diff --git a/src/soundLoop.js b/src/soundLoop.js index 4375dfba..1e5ce9d3 100644 --- a/src/soundLoop.js +++ b/src/soundLoop.js @@ -305,7 +305,7 @@ define(function (require) { return this._interval; }, set: function (interval) { - this.musicalTimeMode = typeof interval === 'Number' ? false : true; + this.musicalTimeMode = typeof interval === 'number' ? false : true; this._interval = interval; this._update(); }, diff --git a/test/tests/p5.Amplitude.js b/test/tests/p5.Amplitude.js index 1be92ddf..c65f4cbf 100644 --- a/test/tests/p5.Amplitude.js +++ b/test/tests/p5.Amplitude.js @@ -6,7 +6,7 @@ define(['chai'], function (chai) { describe('p5.Amplitude', function () { this.timeout(1000); - var sf, amp; + var sf, amp, osc, oAmp; it('can be created', function () { amp = new p5.Amplitude(); @@ -19,7 +19,6 @@ define(['chai'], function (chai) { done(); }); - var osc, oAmp; it('accepts oscillator input', function () { osc = new p5.Oscillator('square'); osc.amp(1); diff --git a/test/tests/p5.AudioVoice.js b/test/tests/p5.AudioVoice.js index 543822c4..3f7df606 100644 --- a/test/tests/p5.AudioVoice.js +++ b/test/tests/p5.AudioVoice.js @@ -1,8 +1,6 @@ 'use strict'; define(['chai'], function (chai) { - var expect = chai.expect; - describe('p5.AudioVoice', function () { it('can be created and disposed', function () { var av = new p5.AudioVoice(); From 6c9d3a359bdefebdbce21fea0540920352bb9181 Mon Sep 17 00:00:00 2001 From: Jason Sigal Date: Thu, 14 May 2020 01:43:42 -0400 Subject: [PATCH 3/9] Create ci-lint.yml lint PR's --- .github/workflows/ci-lint.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/ci-lint.yml diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml new file mode 100644 index 00000000..876a5449 --- /dev/null +++ b/.github/workflows/ci-lint.yml @@ -0,0 +1,28 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x, 12.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm lint From 8bf5ee45428e37668131d2560205475d9049c5f9 Mon Sep 17 00:00:00 2001 From: Jason Sigal Date: Thu, 14 May 2020 22:11:38 -0400 Subject: [PATCH 4/9] ci-lint: npm run lint was missing the word run before --- .github/workflows/ci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml index 876a5449..3e89255a 100644 --- a/.github/workflows/ci-lint.yml +++ b/.github/workflows/ci-lint.yml @@ -25,4 +25,4 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm ci - - run: npm lint + - run: npm run lint From 12e89b335cd91cfea5de4804de075cd0454831e7 Mon Sep 17 00:00:00 2001 From: Divyanshu Raj Date: Fri, 15 May 2020 16:20:53 +0530 Subject: [PATCH 5/9] added test.js file for lint and pretify and added tslint-config-prettier as a dev depen --- .eslintignore | 1 - .prettierignore | 1 - package-lock.json | 3 ++- package.json | 4 ++-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.eslintignore b/.eslintignore index f1c00568..62f6032e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,3 @@ Gruntfile.js -test/test.js webpack.config.js lib/ diff --git a/.prettierignore b/.prettierignore index f1c00568..62f6032e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ Gruntfile.js -test/test.js webpack.config.js lib/ diff --git a/package-lock.json b/package-lock.json index b3ed22db..34013294 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7392,7 +7392,8 @@ "tslint-config-prettier": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==" + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true }, "tty-browserify": { "version": "0.0.0", diff --git a/package.json b/package.json index f4f09928..91213b1c 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "grunt-webpack": "^3.1.3", "prettier": "2.0.5", "raw-loader": "^3.0.0", + "tslint-config-prettier": "^1.18.0", "uglify-loader": "^3.0.0", "uglifyjs-webpack-plugin": "^2.1.3", "webpack": "^4.33.0", @@ -33,8 +34,7 @@ "dependencies": { "audioworklet-polyfill": "^1.1.2", "startaudiocontext": "^1.2.1", - "tone": "0.10.0", - "tslint-config-prettier": "^1.18.0" + "tone": "0.10.0" }, "scripts": { "build": "grunt", From 1a4cd84ec70f6b7899fa352493a7ddca651fbe89 Mon Sep 17 00:00:00 2001 From: Divyanshu Raj Date: Fri, 15 May 2020 16:41:29 +0530 Subject: [PATCH 6/9] added pre-commit hook --- Gruntfile.js | 8 +++++- package-lock.json | 70 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 ++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 8960267f..43580c74 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -53,7 +53,12 @@ module.exports = function(grunt) { hostname: '*' } } - } + }, + githooks: { + all: { + 'pre-commit':'lint' //runs linting test before every git commit + } + } }); @@ -62,6 +67,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-open'); grunt.loadNpmTasks('grunt-decomment'); + grunt.loadNpmTasks('grunt-githooks'); grunt.registerTask('lint', ['eslint:source']); grunt.registerTask('default', ['webpack:prod', 'decomment']); diff --git a/package-lock.json b/package-lock.json index b5a1f5f1..cfeb74d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1186,6 +1186,12 @@ "lodash": "2.x" } }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -4244,6 +4250,15 @@ "eslint": "^4.0.0" } }, + "grunt-githooks": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/grunt-githooks/-/grunt-githooks-0.6.0.tgz", + "integrity": "sha1-EMakDFN8G2xlZIxrft8AGKAPw/A=", + "dev": true, + "requires": { + "handlebars": "~1.0.12" + } + }, "grunt-legacy-log": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", @@ -4411,6 +4426,44 @@ } } }, + "handlebars": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-1.0.12.tgz", + "integrity": "sha1-GMbTRAw16RsZs/9YK5FRq0mF1Pw=", + "dev": true, + "requires": { + "optimist": "~0.3", + "uglify-js": "~2.3" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "uglify-js": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", + "integrity": "sha1-+gmEdwtCi3qbKoBY9GNV0U/vIRo=", + "dev": true, + "requires": { + "async": "~0.2.6", + "optimist": "~0.3.5", + "source-map": "~0.1.7" + } + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -5750,6 +5803,23 @@ "pinkie-promise": "^2.0.0" } }, + "optimist": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", + "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", + "dev": true, + "requires": { + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", diff --git a/package.json b/package.json index ed1554ac..76104564 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "grunt-contrib-connect": "^1.0.2", "grunt-decomment": "^0.2.4", "grunt-eslint": "^20.0.0", + "grunt-githooks": "^0.6.0", "grunt-mocha": "^1.0.4", "grunt-open": "^0.2.3", "grunt-webpack": "^3.1.3", @@ -36,6 +37,7 @@ "build": "grunt", "test": "grunt run-tests", "lint": "grunt lint", - "dev": "grunt dev" + "dev": "grunt dev", + "postinstall": "grunt githooks" } } From d1884bbdd99235de0adcaf47e0c1faa416d0acad Mon Sep 17 00:00:00 2001 From: Divyanshu Raj Date: Fri, 15 May 2020 16:41:29 +0530 Subject: [PATCH 7/9] added pre-commit hook --- Gruntfile.js | 8 +++++- package-lock.json | 70 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 ++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index b47c92ab..5f7d56c9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -56,7 +56,12 @@ module.exports = function(grunt) { hostname: '*' } } - } + }, + githooks: { + all: { + 'pre-commit':'lint' //runs linting test before every git commit + } + } }); @@ -65,6 +70,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-open'); grunt.loadNpmTasks('grunt-decomment'); + grunt.loadNpmTasks('grunt-githooks'); grunt.registerTask('lint', ['eslint:source']); grunt.registerTask('default', ['webpack:prod', 'decomment']); diff --git a/package-lock.json b/package-lock.json index 34013294..bf8d9408 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1186,6 +1186,12 @@ "lodash": "2.x" } }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -4274,6 +4280,15 @@ "eslint": "^4.0.0" } }, + "grunt-githooks": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/grunt-githooks/-/grunt-githooks-0.6.0.tgz", + "integrity": "sha1-EMakDFN8G2xlZIxrft8AGKAPw/A=", + "dev": true, + "requires": { + "handlebars": "~1.0.12" + } + }, "grunt-legacy-log": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", @@ -4441,6 +4456,44 @@ } } }, + "handlebars": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-1.0.12.tgz", + "integrity": "sha1-GMbTRAw16RsZs/9YK5FRq0mF1Pw=", + "dev": true, + "requires": { + "optimist": "~0.3", + "uglify-js": "~2.3" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "uglify-js": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", + "integrity": "sha1-+gmEdwtCi3qbKoBY9GNV0U/vIRo=", + "dev": true, + "requires": { + "async": "~0.2.6", + "optimist": "~0.3.5", + "source-map": "~0.1.7" + } + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -5780,6 +5833,23 @@ "pinkie-promise": "^2.0.0" } }, + "optimist": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", + "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=", + "dev": true, + "requires": { + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", diff --git a/package.json b/package.json index 91213b1c..d0a79582 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "grunt-contrib-connect": "^1.0.2", "grunt-decomment": "^0.2.4", "grunt-eslint": "^20.0.0", + "grunt-githooks": "^0.6.0", "grunt-mocha": "^1.0.4", "grunt-open": "^0.2.3", "grunt-webpack": "^3.1.3", @@ -40,6 +41,7 @@ "build": "grunt", "test": "grunt run-tests", "lint": "grunt lint", - "dev": "grunt dev" + "dev": "grunt dev", + "postinstall": "grunt githooks" } } From e815bee3a76c184762defe1709adff57538c8d92 Mon Sep 17 00:00:00 2001 From: kyle1james Date: Sat, 16 May 2020 07:42:48 -0400 Subject: [PATCH 8/9] rebase with master --- lib/p5.sound.js | 2338 ++++++++++++++++++++++----------------- lib/p5.sound.js.map | 2 +- lib/p5.sound.min.js | 4 +- lib/p5.sound.min.js.map | 2 +- 4 files changed, 1323 insertions(+), 1023 deletions(-) diff --git a/lib/p5.sound.js b/lib/p5.sound.js index 8580643c..9ac698e1 100644 --- a/lib/p5.sound.js +++ b/lib/p5.sound.js @@ -1,4 +1,4 @@ -/** [p5.sound] Version: 0.3.12 - 2020-01-06 */ +/** [p5.sound] Version: 0.3.12 - 2020-05-16 */ /** *

p5.sound extends p5 with Web Audio functionality including audio input, @@ -70,96 +70,136 @@ * Web Audio API: http://w3.org/TR/webaudio/ */ - (function(modules) { - var installedModules = {}; - function __webpack_require__(moduleId) { - if(installedModules[moduleId]) { - return installedModules[moduleId].exports; - } - var module = installedModules[moduleId] = { - i: moduleId, - l: false, - exports: {} - }; - modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - module.l = true; - return module.exports; - } - __webpack_require__.m = modules; - __webpack_require__.c = installedModules; - __webpack_require__.d = function(exports, name, getter) { - if(!__webpack_require__.o(exports, name)) { - Object.defineProperty(exports, name, { enumerable: true, get: getter }); - } - }; - __webpack_require__.r = function(exports) { - if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { - Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); - } - Object.defineProperty(exports, '__esModule', { value: true }); - }; - __webpack_require__.t = function(value, mode) { - if(mode & 1) value = __webpack_require__(value); - if(mode & 8) return value; - if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; - var ns = Object.create(null); - __webpack_require__.r(ns); - Object.defineProperty(ns, 'default', { enumerable: true, value: value }); - if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); - return ns; - }; - __webpack_require__.n = function(module) { - var getter = module && module.__esModule ? - function getDefault() { return module['default']; } : - function getModuleExports() { return module; }; - __webpack_require__.d(getter, 'a', getter); - return getter; - }; - __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; - __webpack_require__.p = ""; - return __webpack_require__(__webpack_require__.s = 31); - }) - ([ - (function(module, exports, __webpack_require__) { +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 31); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { var __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 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + if (typeof vol === 'number') { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; var currentVol = p5sound.output.gain.value; p5sound.output.gain.cancelScheduledValues(now + tFromNow); @@ -215,6 +256,7 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; } else if (vol) { vol.connect(p5sound.output.gain); } else { + // return the Gain Node return p5sound.output.gain; } }; @@ -228,7 +270,9 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.prototype.soundOut = p5.soundOut = p5sound; + p5.prototype.soundOut = p5.soundOut = p5sound; // a silent connection to the DesinationNode + // which will ensure that anything connected to it + // will not be garbage collected p5.soundOut._silentNode = p5sound.audiocontext.createGain(); p5.soundOut._silentNode.gain.value = 0; @@ -239,20 +283,30 @@ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { -var __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__), +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(4),__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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +var __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 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var now = p5sound.audiocontext.currentTime; + var startTime = now + tFromNow; + var endTime = startTime + rampTime + 0.001; var currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(now); - this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001); - this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001); + this.output.gain.linearRampToValueAtTime(currentVol, startTime + 0.001); + this.output.gain.linearRampToValueAtTime(vol, endTime); }; /** * Link effects together in a chain @@ -365,7 +421,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Effect.prototype.drywet = function (fade) { - if (typeof fade !== "undefined") { + if (typeof fade !== 'undefined') { this._drywet.fade.value = fade; } @@ -399,6 +455,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Effect.prototype.dispose = function () { + // remove refernce form soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -430,14 +487,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { - -var __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 -1) { - if (p5.prototype.isFileSupported(extTest)) { - path = path; - } else { + if (!p5.prototype.isFileSupported(extTest)) { var pathSplit = path.split('.'); var pathCore = pathSplit[pathSplit.length - 1]; - for (var i = 0; i < p5sound.extensions.length; i++) { - var extension = p5sound.extensions[i]; - var supported = p5.prototype.isFileSupported(extension); + for (var _i = 0; _i < p5sound.extensions.length; _i++) { + var _extension = p5sound.extensions[_i]; + + var _supported = p5.prototype.isFileSupported(_extension); - if (supported) { + if (_supported) { pathCore = ''; if (pathSplit.length === 2) { pathCore += pathSplit[0]; } - for (var i = 1; i <= pathSplit.length - 2; i++) { - var p = pathSplit[i]; + for (var _i2 = 1; _i2 <= pathSplit.length - 2; _i2++) { + var p = pathSplit[_i2]; pathCore += '.' + p; } path = pathCore += '.'; - path = path += extension; + path = path += _extension; break; } } } - } + } // if no extension is provided... else { - for (var i = 0; i < p5sound.extensions.length; i++) { - var extension = p5sound.extensions[i]; - var supported = p5.prototype.isFileSupported(extension); + for (var _i3 = 0; _i3 < p5sound.extensions.length; _i3++) { + var _extension2 = p5sound.extensions[_i3]; - if (supported) { - path = path + '.' + extension; + var _supported2 = p5.prototype.isFileSupported(_extension2); + + if (_supported2) { + path = path + '.' + _extension2; break; } } } - } + } // end 'if string' + // path can either be a single string, or an array else if (_typeof(paths) === 'object') { for (var i = 0; i < paths.length; i++) { var extension = paths[i].split('.').pop(); var supported = p5.prototype.isFileSupported(extension); if (supported) { + // console.log('.'+extension + ' is ' + supported + + // ' supported by your browser.'); path = paths[i]; break; } @@ -691,6 +748,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat p5.prototype._mathChain = function (o, math, thisChain, nextChain, type) { + // if this type of math already exists in the chain, replace it for (var i in o.mathOps) { if (o.mathOps[i] instanceof type) { o.mathOps[i].dispose(); @@ -707,12 +765,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat math.connect(nextChain); o.mathOps[thisChain] = math; return o; - }; + }; // helper methods to convert audio file as .wav format, + // will use as saving .wav file and saving blob object + // Thank you to Matt Diamond's RecorderJS (MIT License) + // https://github.com/mattdiamond/Recorderjs function convertToWav(audioBuffer) { var leftChannel, rightChannel; - leftChannel = audioBuffer.getChannelData(0); + leftChannel = audioBuffer.getChannelData(0); // handle mono files if (audioBuffer.numberOfChannels > 1) { rightChannel = audioBuffer.getChannelData(1); @@ -720,39 +781,41 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat rightChannel = leftChannel; } - var interleaved = interleave(leftChannel, rightChannel); + var interleaved = interleave(leftChannel, rightChannel); // create the buffer and view to create the .WAV file var buffer = new window.ArrayBuffer(44 + interleaved.length * 2); - var view = new window.DataView(buffer); + var view = new window.DataView(buffer); // write the WAV container, + // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf + // RIFF chunk descriptor writeUTFBytes(view, 0, 'RIFF'); view.setUint32(4, 36 + interleaved.length * 2, true); - writeUTFBytes(view, 8, 'WAVE'); + writeUTFBytes(view, 8, 'WAVE'); // FMT sub-chunk writeUTFBytes(view, 12, 'fmt '); view.setUint32(16, 16, true); - view.setUint16(20, 1, true); + view.setUint16(20, 1, true); // stereo (2 channels) view.setUint16(22, 2, true); view.setUint32(24, p5sound.audiocontext.sampleRate, true); view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true); view.setUint16(32, 4, true); - view.setUint16(34, 16, true); + view.setUint16(34, 16, true); // data sub-chunk writeUTFBytes(view, 36, 'data'); - view.setUint32(40, interleaved.length * 2, true); + view.setUint32(40, interleaved.length * 2, true); // write the PCM samples var lng = interleaved.length; var index = 44; var volume = 1; for (var i = 0; i < lng; i++) { - view.setInt16(index, interleaved[i] * (0x7FFF * volume), true); + view.setInt16(index, interleaved[i] * (0x7fff * volume), true); index += 2; } return view; - } + } // helper methods to save waves function interleave(leftChannel, rightChannel) { @@ -778,7 +841,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } function safeBufferSize(idealBufferSize) { - var bufferSize = idealBufferSize; + var bufferSize = idealBufferSize; // if the AudioWorkletNode is actually a ScriptProcessorNode created via polyfill, + // make sure that our chosen buffer size isn't smaller than the buffer size automatically + // selected by the polyfill + // reference: https://github.com/GoogleChromeLabs/audioworklet-polyfill/issues/13#issuecomment-425014930 var tempAudioWorkletNode = new AudioWorkletNode(p5sound.audiocontext, processorNames.soundFileProcessor); @@ -800,26 +866,30 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(20),__webpack_require__(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__), +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(20),__webpack_require__(45),__webpack_require__(46),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(t){return t.Type={Default:"number",Time:"time",Frequency:"frequency",TransportTime:"transportTime",Ticks:"ticks",NormalRange:"normalRange",AudioRange:"audioRange",Decibels:"db",Interval:"interval",BPM:"bpm",Positive:"positive",Cents:"cents",Degrees:"degrees",MIDI:"midi",BarsBeatsSixteenths:"barsBeatsSixteenths",Samples:"samples",Hertz:"hertz",Note:"note",Milliseconds:"milliseconds",Seconds:"seconds",Notation:"notation"},t.prototype.toSeconds=function(e){return this.isNumber(e)?e:this.isUndef(e)?this.now():this.isString(e)?new t.Time(e).toSeconds():e instanceof t.TimeBase?e.toSeconds():void 0},t.prototype.toFrequency=function(e){return this.isNumber(e)?e:this.isString(e)||this.isUndef(e)?new t.Frequency(e).valueOf():e instanceof t.TimeBase?e.toFrequency():void 0},t.prototype.toTicks=function(e){return this.isNumber(e)||this.isString(e)?new t.TransportTime(e).toTicks():this.isUndef(e)?t.Transport.ticks:e instanceof t.TimeBase?e.toTicks():void 0},t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { var __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:1e)this.cancelScheduledValues(e),this.linearRampToValueAtTime(t,e);else{var n=this._searchAfter(e);n&&(this.cancelScheduledValues(e),n.type===o.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(t,e):n.type===o.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(t,e)),this.setValueAtTime(t,e)}return this},o.TimelineSignal.prototype.linearRampToValueBetween=function(e,t,i){return this.setRampPoint(t),this.linearRampToValueAtTime(e,i),this},o.TimelineSignal.prototype.exponentialRampToValueBetween=function(e,t,i){return this.setRampPoint(t),this.exponentialRampToValueAtTime(e,i),this},o.TimelineSignal.prototype._searchBefore=function(e){return this._events.get(e)},o.TimelineSignal.prototype._searchAfter=function(e){return this._events.getAfter(e)},o.TimelineSignal.prototype.getValueAtTime=function(e){e=this.toSeconds(e);var t=this._searchAfter(e),i=this._searchBefore(e),n=this._initial;if(null===i)n=this._initial;else if(i.type===o.TimelineSignal.Type.Target){var a,l=this._events.getBefore(i.time);a=null===l?this._initial:l.value,n=this._exponentialApproach(i.time,a,i.value,i.constant,e)}else n=i.type===o.TimelineSignal.Type.Curve?this._curveInterpolate(i.time,i.value,i.duration,e):null===t?i.value:t.type===o.TimelineSignal.Type.Linear?this._linearInterpolate(i.time,i.value,t.time,t.value,e):t.type===o.TimelineSignal.Type.Exponential?this._exponentialInterpolate(i.time,i.value,t.time,t.value,e):i.value;return n},o.TimelineSignal.prototype.connect=o.SignalBase.prototype.connect,o.TimelineSignal.prototype._exponentialApproach=function(e,t,i,n,a){return i+(t-i)*Math.exp(-(a-e)/n)},o.TimelineSignal.prototype._linearInterpolate=function(e,t,i,n,a){return t+(a-e)/(i-e)*(n-t)},o.TimelineSignal.prototype._exponentialInterpolate=function(e,t,i,n,a){return(t=Math.max(this._minOutput,t))*Math.pow(n/t,(a-e)/(i-e))},o.TimelineSignal.prototype._curveInterpolate=function(e,t,i,n){var a=t.length;if(e+i<=n)return t[a-1];if(n<=e)return t[0];var l=(n-e)/i,s=Math.floor((a-1)*l),r=Math.ceil((a-1)*l),o=t[s],p=t[r];return r===s?o:this._linearInterpolate(s,o,r,p,l*(a-1))},o.TimelineSignal.prototype.dispose=function(){o.Signal.prototype.dispose.call(this),o.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},o.TimelineSignal}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var Effect = __webpack_require__(4); + var Effect = __webpack_require__(5); /** *

A p5.Filter uses a Web Audio Biquad Filter to filter * the frequency response of an input source. Subclasses @@ -907,70 +999,70 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass' * @example *

- * let fft, noise, filter; - * - * function setup() { - * let cnv = createCanvas(100,100); - * cnv.mousePressed(makeNoise); - * fill(255, 0, 255); - * - * filter = new p5.BandPass(); - * noise = new p5.Noise(); - * noise.disconnect(); - * noise.connect(filter); - * - * fft = new p5.FFT(); - * } - * - * function draw() { - * background(220); - * - * // set the BandPass frequency based on mouseX - * let freq = map(mouseX, 0, width, 20, 10000); - * freq = constrain(freq, 0, 22050); - * filter.freq(freq); - * // give the filter a narrow band (lower res = wider bandpass) - * filter.res(50); - * - * // draw filtered spectrum - * let spectrum = fft.analyze(); - * noStroke(); - * for (let i = 0; i < spectrum.length; i++) { - * let x = map(i, 0, spectrum.length, 0, width); - * let h = -height + map(spectrum[i], 0, 255, height, 0); - * rect(x, height, width/spectrum.length, h); - * } - * if (!noise.started) { - * text('tap here and drag to change frequency', 10, 20, width - 20); - * } else { - * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20); - * } - * } - * - * function makeNoise() { - * // see also: `userStartAudio()` - * noise.start(); - * noise.amp(0.5, 0.2); - * } - * - * function mouseReleased() { - * noise.amp(0, 0.2); - * } - * + * let fft, noise, filter; + * + * function setup() { + * let cnv = createCanvas(100,100); + * cnv.mousePressed(makeNoise); + * fill(255, 0, 255); + * + * filter = new p5.BandPass(); + * noise = new p5.Noise(); + * noise.disconnect(); + * noise.connect(filter); + * + * fft = new p5.FFT(); + * } + * + * function draw() { + * background(220); + * + * // set the BandPass frequency based on mouseX + * let freq = map(mouseX, 0, width, 20, 10000); + * freq = constrain(freq, 0, 22050); + * filter.freq(freq); + * // give the filter a narrow band (lower res = wider bandpass) + * filter.res(50); + * + * // draw filtered spectrum + * let spectrum = fft.analyze(); + * noStroke(); + * for (let i = 0; i < spectrum.length; i++) { + * let x = map(i, 0, spectrum.length, 0, width); + * let h = -height + map(spectrum[i], 0, 255, height, 0); + * rect(x, height, width/spectrum.length, h); + * } + * if (!noise.started) { + * text('tap here and drag to change frequency', 10, 20, width - 20); + * } else { + * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20); + * } + * } + * + * function makeNoise() { + * // see also: `userStartAudio()` + * noise.start(); + * noise.amp(0.5, 0.2); + * } + * + * function mouseReleased() { + * noise.amp(0, 0.2); + * } + * *
*/ p5.Filter = function (type) { - Effect.call(this); + Effect.call(this); //add extend Effect by adding a Biquad Filter /** - * The p5.Filter is built with a - * - * Web Audio BiquadFilter Node. - * - * @property {DelayNode} biquadFilter - */ + * The p5.Filter is built with a + * + * Web Audio BiquadFilter Node. + * + * @property {DelayNode} biquadFilter + */ this.biquad = this.ac.createBiquadFilter(); this.input.connect(this.biquad); @@ -978,7 +1070,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (type) { this.setType(type); - } + } //Properties useful for the toggle method. this._on = true; @@ -1137,6 +1229,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Filter.prototype.dispose = function () { + // remove reference from soundArray Effect.prototype.dispose.apply(this); if (this.biquad) { @@ -1197,21 +1290,24 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(25),__webpack_require__(2),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(n){"use strict";return n.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new n.Gain,this._neg=new n.Negate,this._param=this.input[1]=new n.Signal(t),this._param.chain(this._neg,this._sum)},n.extend(n.Subtract,n.Signal),n.Subtract.prototype.dispose=function(){return n.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},n.Subtract}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; +/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; global.TONE_SILENCE_VERSION_LOGGING = true; -!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(35), __webpack_require__(12), __webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (StartAudioContext, Context, Tone) { - var audiocontext = new window.AudioContext(); +!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(35), __webpack_require__(11), __webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function (StartAudioContext, Context, Tone) { + // Create the Audio Context + var audiocontext = new window.AudioContext(); // Tone and p5.sound share the same audio context Tone.context.dispose(); Tone.setContext(audiocontext); @@ -1326,40 +1422,46 @@ global.TONE_SILENCE_VERSION_LOGGING = true; return audiocontext; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); -}.call(this, __webpack_require__(34))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(34))) - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.Emitter=function(){this._events={}},o.extend(o.Emitter),o.Emitter.prototype.on=function(t,e){for(var i=t.split(/\W+/),r=0;r 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; if (typeof vol === 'number') { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var now = p5sound.audiocontext.currentTime; this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime); } else if (vol) { - vol.connect(self.output.gain); + vol.connect(this.output.gain); } else { + // return the Gain Node return this.output.gain; } - }; + }; // these are now the same thing p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp; @@ -1621,13 +1724,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.Oscillator.prototype.freq = function (val, rampTime, tFromNow) { + p5.Oscillator.prototype.freq = function (val) { + var rampTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + if (typeof val === 'number' && !isNaN(val)) { this.f = val; var now = p5sound.audiocontext.currentTime; - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; - var t = now + tFromNow + rampTime; if (rampTime === 0) { this.oscillator.frequency.setValueAtTime(val, tFromNow + now); @@ -1637,7 +1740,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } else { this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now); } - } + } // reset phase if oscillator has a phase if (this.phaseAmount) { @@ -1648,10 +1751,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; val = val.output; } - val.connect(this.oscillator.frequency); + val.connect(this.oscillator.frequency); // keep track of what is modulating this param + // so it can be re-connected if this._freqMods.push(val); } else { + // return the Frequency Node return this.oscillator.frequency; } }; @@ -1736,10 +1841,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Oscillator.prototype.getPan = function () { return this.panPosition; - }; + }; // get rid of the oscillator p5.Oscillator.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -1749,7 +1855,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.disconnect(); this.panner = null; this.oscillator = null; - } + } // if it is a Pulse if (this.osc2) { @@ -1773,26 +1879,30 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.phaseAmount = p; if (!this.dNode) { - this.dNode = p5sound.audiocontext.createDelay(); + // create a delay node + this.dNode = p5sound.audiocontext.createDelay(); // put the delay node in between output and panner this.oscillator.disconnect(); this.oscillator.connect(this.dNode); this.dNode.connect(this.output); - } + } // set delay time to match phase: this.dNode.delayTime.setValueAtTime(delayAmt, now); - }; + }; // ========================== // + // SIGNAL MATH FOR MODULATION // + // ========================== // + // return sigChain(this, scale, thisChain, nextChain, Scale); var sigChain = function sigChain(o, mathObj, thisChain, nextChain, type) { - var chainSource = o.oscillator; + var chainSource = o.oscillator; // if this type of math already exists in the chain, replace it for (var i in o.mathOps) { if (o.mathOps[i] instanceof type) { chainSource.disconnect(); o.mathOps[i].dispose(); - thisChain = i; + thisChain = i; // assume nextChain is output gain node unless... if (thisChain < o.mathOps.length - 2) { nextChain = o.mathOps[i + 1]; @@ -1802,7 +1912,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (thisChain === o.mathOps.length - 1) { o.mathOps.push(nextChain); - } + } // assume source is the oscillator unless i > 0 if (i > 0) { @@ -1884,8 +1994,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var scale = new Scale(mapOutMin, mapOutMax); var thisChain = this.mathOps.length - 1; var nextChain = this.output; - return sigChain(this, scale, thisChain, nextChain, Scale); - }; + return sigChain(this, scale, thisChain, nextChain, Scale); // this.output.disconnect(); + // this.output.connect(scale) + }; // ============================== // + // SinOsc, TriOsc, SqrOsc, SawOsc // + // ============================== // /** * Constructor: new p5.SinOsc(). @@ -1967,32 +2080,37 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { var __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=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(0e)return r;s.time>e?n=r:s.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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { var __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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(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__), +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(3),__webpack_require__(4)], __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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { -var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(14),__webpack_require__(66),__webpack_require__(18),__webpack_require__(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("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var s=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(s),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), +var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(14),__webpack_require__(66),__webpack_require__(18),__webpack_require__(11)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var i=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=i.time,this.isUndef(i.offset)||(this.ticks=i.offset),this.emit("start",i.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",i.time)):e===o.State.Paused&&this.emit("pause",i.time)}var s=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(s),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -2006,56 +2124,56 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var DEFAULT_SUSTAIN = 0.15; /** - * A MonoSynth is used as a single voice for sound synthesis. - * This is a class to be used in conjunction with the PolySynth - * class. Custom synthetisers should be built inheriting from - * this class. - * - * @class p5.MonoSynth - * @constructor - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * textAlign(CENTER); - * text('tap to play', width/2, height/2); - * - * monoSynth = new p5.MonoSynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * let note = random(['Fb4', 'G4']); - * // note velocity (volume, from 0 to 1) - * let velocity = random(); - * // time from now (in seconds) - * let time = 0; - * // note duration (in seconds) - * let dur = 1/6; - * - * monoSynth.play(note, velocity, time, dur); - * } - *
- **/ + * A MonoSynth is used as a single voice for sound synthesis. + * This is a class to be used in conjunction with the PolySynth + * class. Custom synthetisers should be built inheriting from + * this class. + * + * @class p5.MonoSynth + * @constructor + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * textAlign(CENTER); + * text('tap to play', width/2, height/2); + * + * monoSynth = new p5.MonoSynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * let note = random(['Fb4', 'G4']); + * // note velocity (volume, from 0 to 1) + * let velocity = random(); + * // time from now (in seconds) + * let time = 0; + * // note duration (in seconds) + * let dur = 1/6; + * + * monoSynth.play(note, velocity, time, dur); + * } + *
+ **/ p5.MonoSynth = function () { AudioVoice.call(this); this.oscillator = new p5.Oscillator(); this.env = new p5.Envelope(); this.env.setRange(1, 0); - this.env.setExp(true); + this.env.setExp(true); //set params - this.setADSR(0.02, 0.25, 0.05, 0.35); + this.setADSR(0.02, 0.25, 0.05, 0.35); // oscillator --> env --> this.output (gain) --> p5.soundOut this.oscillator.disconnect(); this.oscillator.connect(this.output); this.env.disconnect(); - this.env.setInput(this.output.gain); + this.env.setInput(this.output.gain); // reset oscillator gain to 1.0 this.oscillator.output.gain.value = 1.0; this.oscillator.start(); @@ -2065,159 +2183,159 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype); /** - * Play tells the MonoSynth to start playing a note. This method schedules - * the calling of .triggerAttack and .triggerRelease. - * - * @method play - * @for p5.MonoSynth - * @param {String | Number} note the note you want to play, specified as a - * frequency in Hertz (Number) or as a midi - * value in Note/Octave format ("C4", "Eb3"...etc") - * See - * Tone. Defaults to 440 hz. - * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) - * @param {Number} [secondsFromNow] time from now (in seconds) at which to play - * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds. - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * textAlign(CENTER); - * text('tap to play', width/2, height/2); - * - * monoSynth = new p5.MonoSynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * let note = random(['Fb4', 'G4']); - * // note velocity (volume, from 0 to 1) - * let velocity = random(); - * // time from now (in seconds) - * let time = 0; - * // note duration (in seconds) - * let dur = 1/6; - * - * monoSynth.play(note, velocity, time, dur); - * } - *
- * - */ + * Play tells the MonoSynth to start playing a note. This method schedules + * the calling of .triggerAttack and .triggerRelease. + * + * @method play + * @for p5.MonoSynth + * @param {String | Number} note the note you want to play, specified as a + * frequency in Hertz (Number) or as a midi + * value in Note/Octave format ("C4", "Eb3"...etc") + * See + * Tone. Defaults to 440 hz. + * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) + * @param {Number} [secondsFromNow] time from now (in seconds) at which to play + * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds. + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * textAlign(CENTER); + * text('tap to play', width/2, height/2); + * + * monoSynth = new p5.MonoSynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * let note = random(['Fb4', 'G4']); + * // note velocity (volume, from 0 to 1) + * let velocity = random(); + * // time from now (in seconds) + * let time = 0; + * // note duration (in seconds) + * let dur = 1/6; + * + * monoSynth.play(note, velocity, time, dur); + * } + *
+ * + */ p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) { this.triggerAttack(note, velocity, ~~secondsFromNow); this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN)); }; /** - * Trigger the Attack, and Decay portion of the Envelope. - * Similar to holding down a key on a piano, but it will - * hold the sustain level until you let go. - * - * @param {String | Number} note the note you want to play, specified as a - * frequency in Hertz (Number) or as a midi - * value in Note/Octave format ("C4", "Eb3"...etc") - * See - * Tone. Defaults to 440 hz - * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) - * @param {Number} [secondsFromNow] time from now (in seconds) at which to play - * @method triggerAttack - * @for p5.MonoSynth - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(triggerAttack); - * background(220); - * text('tap here for attack, let go to release', 5, 20, width - 20); - * monoSynth = new p5.MonoSynth(); - * } - * - * function triggerAttack() { - * userStartAudio(); - * - * monoSynth.triggerAttack("E3"); - * } - * - * function mouseReleased() { - * monoSynth.triggerRelease(); - * } - *
- */ + * Trigger the Attack, and Decay portion of the Envelope. + * Similar to holding down a key on a piano, but it will + * hold the sustain level until you let go. + * + * @param {String | Number} note the note you want to play, specified as a + * frequency in Hertz (Number) or as a midi + * value in Note/Octave format ("C4", "Eb3"...etc") + * See + * Tone. Defaults to 440 hz + * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1) + * @param {Number} [secondsFromNow] time from now (in seconds) at which to play + * @method triggerAttack + * @for p5.MonoSynth + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(triggerAttack); + * background(220); + * text('tap here for attack, let go to release', 5, 20, width - 20); + * monoSynth = new p5.MonoSynth(); + * } + * + * function triggerAttack() { + * userStartAudio(); + * + * monoSynth.triggerAttack("E3"); + * } + * + * function mouseReleased() { + * monoSynth.triggerRelease(); + * } + *
+ */ - p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) { - var secondsFromNow = ~~secondsFromNow; + p5.MonoSynth.prototype.triggerAttack = function (note, velocity) { + var secondsFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var freq = noteToFreq(note); var vel = velocity || 0.1; this.oscillator.freq(freq, 0, secondsFromNow); this.env.ramp(this.output.gain, secondsFromNow, vel); }; /** - * Trigger the release of the Envelope. This is similar to releasing - * the key on a piano and letting the sound fade according to the - * release level and release time. - * - * @param {Number} secondsFromNow time to trigger the release - * @method triggerRelease - * @for p5.MonoSynth - * @example - *
- * let monoSynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(triggerAttack); - * background(220); - * text('tap here for attack, let go to release', 5, 20, width - 20); - * monoSynth = new p5.MonoSynth(); - * } - * - * function triggerAttack() { - * userStartAudio(); - * - * monoSynth.triggerAttack("E3"); - * } - * - * function mouseReleased() { - * monoSynth.triggerRelease(); - * } - *
- */ + * Trigger the release of the Envelope. This is similar to releasing + * the key on a piano and letting the sound fade according to the + * release level and release time. + * + * @param {Number} secondsFromNow time to trigger the release + * @method triggerRelease + * @for p5.MonoSynth + * @example + *
+ * let monoSynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(triggerAttack); + * background(220); + * text('tap here for attack, let go to release', 5, 20, width - 20); + * monoSynth = new p5.MonoSynth(); + * } + * + * function triggerAttack() { + * userStartAudio(); + * + * monoSynth.triggerAttack("E3"); + * } + * + * function mouseReleased() { + * monoSynth.triggerRelease(); + * } + *
+ */ - p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) { - var secondsFromNow = secondsFromNow || 0; + p5.MonoSynth.prototype.triggerRelease = function () { + var secondsFromNow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; this.env.ramp(this.output.gain, secondsFromNow, 0); }; /** - * Set values like a traditional - * - * ADSR envelope - * . - * - * @method setADSR - * @for p5.MonoSynth - * @param {Number} attackTime Time (in seconds before envelope - * reaches Attack Level - * @param {Number} [decayTime] Time (in seconds) before envelope - * reaches Decay/Sustain Level - * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1, - * where 1.0 = attackLevel, 0.0 = releaseLevel. - * The susRatio determines the decayLevel and the level at which the - * sustain portion of the envelope will sustain. - * For example, if attackLevel is 0.4, releaseLevel is 0, - * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is - * increased to 1.0 (using setRange), - * then decayLevel would increase proportionally, to become 0.5. - * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) - */ + * Set values like a traditional + * + * ADSR envelope + * . + * + * @method setADSR + * @for p5.MonoSynth + * @param {Number} attackTime Time (in seconds before envelope + * reaches Attack Level + * @param {Number} [decayTime] Time (in seconds) before envelope + * reaches Decay/Sustain Level + * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1, + * where 1.0 = attackLevel, 0.0 = releaseLevel. + * The susRatio determines the decayLevel and the level at which the + * sustain portion of the envelope will sustain. + * For example, if attackLevel is 0.4, releaseLevel is 0, + * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is + * increased to 1.0 (using setRange), + * then decayLevel would increase proportionally, to become 0.5. + * @param {Number} [releaseTime] Time in seconds from now (defaults to 0) + */ p5.MonoSynth.prototype.setADSR = function (attack, decay, sustain, release) { @@ -2246,7 +2364,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; Object.defineProperties(p5.MonoSynth.prototype, { - 'attack': { + attack: { get: function get() { return this.env.aTime; }, @@ -2254,7 +2372,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.env.setADSR(attack, this.env.dTime, this.env.sPercent, this.env.rTime); } }, - 'decay': { + decay: { get: function get() { return this.env.dTime; }, @@ -2262,7 +2380,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.env.setADSR(this.env.aTime, decay, this.env.sPercent, this.env.rTime); } }, - 'sustain': { + sustain: { get: function get() { return this.env.sPercent; }, @@ -2270,7 +2388,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.env.setADSR(this.env.aTime, this.env.dTime, sustain, this.env.rTime); } }, - 'release': { + release: { get: function get() { return this.env.rTime; }, @@ -2345,8 +2463,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -2411,8 +2530,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -2424,52 +2544,53 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var noteToFreq = __webpack_require__(6).noteToFreq; /** - * An AudioVoice is used as a single voice for sound synthesis. - * The PolySynth class holds an array of AudioVoice, and deals - * with voices allocations, with setting notes to be played, and - * parameters to be set. - * - * @class p5.PolySynth - * @constructor - * - * @param {Number} [synthVoice] A monophonic synth voice inheriting - * the AudioVoice class. Defaults to p5.MonoSynth - * @param {Number} [maxVoices] Number of voices, defaults to 8; - * @example - *
- * let polySynth; - * - * function setup() { - * let cnv = createCanvas(100, 100); - * cnv.mousePressed(playSynth); - * background(220); - * text('click to play', 20, 20); - * - * polySynth = new p5.PolySynth(); - * } - * - * function playSynth() { - * userStartAudio(); - * - * // note duration (in seconds) - * let dur = 1.5; - * - * // time from now (in seconds) - * let time = 0; - * - * // velocity (volume, from 0 to 1) - * let vel = 0.1; - * - * // notes can overlap with each other - * polySynth.play('G2', vel, 0, dur); - * polySynth.play('C3', vel, time += 1/3, dur); - * polySynth.play('G3', vel, time += 1/3, dur); - * } - *
- **/ + * An AudioVoice is used as a single voice for sound synthesis. + * The PolySynth class holds an array of AudioVoice, and deals + * with voices allocations, with setting notes to be played, and + * parameters to be set. + * + * @class p5.PolySynth + * @constructor + * + * @param {Number} [synthVoice] A monophonic synth voice inheriting + * the AudioVoice class. Defaults to p5.MonoSynth + * @param {Number} [maxVoices] Number of voices, defaults to 8; + * @example + *
+ * let polySynth; + * + * function setup() { + * let cnv = createCanvas(100, 100); + * cnv.mousePressed(playSynth); + * background(220); + * text('click to play', 20, 20); + * + * polySynth = new p5.PolySynth(); + * } + * + * function playSynth() { + * userStartAudio(); + * + * // note duration (in seconds) + * let dur = 1.5; + * + * // time from now (in seconds) + * let time = 0; + * + * // velocity (volume, from 0 to 1) + * let vel = 0.1; + * + * // notes can overlap with each other + * polySynth.play('G2', vel, 0, dur); + * polySynth.play('C3', vel, time += 1/3, dur); + * polySynth.play('G3', vel, time += 1/3, dur); + * } + *
+ **/ p5.PolySynth = function (audioVoice, maxVoices) { + //audiovoices will contain maxVoices many monophonic synths this.audiovoices = []; /** * An object that holds information about which notes have been played and @@ -2480,7 +2601,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @property notes */ - this.notes = {}; + this.notes = {}; //indices of the most recently used, and least recently used audiovoice this._newest = 0; this._oldest = 0; @@ -2500,13 +2621,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; /** * This value must only change as a note is attacked or released. Due to delay * and sustain times, Tone.TimelineSignal is required to schedule the change in value. - * @private + * @private * @property {Tone.TimelineSignal} _voicesInUse */ this._voicesInUse = new TimelineSignal(0); this.output = p5sound.audiocontext.createGain(); - this.connect(); + this.connect(); //Construct the appropriate number of audiovoices this._allocateVoices(); @@ -2570,8 +2691,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.PolySynth.prototype.play = function (note, velocity, secondsFromNow, susTime) { - var susTime = susTime || 1; + p5.PolySynth.prototype.play = function (note, velocity, secondsFromNow) { + var susTime = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; this.noteAttack(note, velocity, secondsFromNow); this.noteRelease(note, secondsFromNow + susTime); }; @@ -2600,9 +2721,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; **/ - p5.PolySynth.prototype.noteADSR = function (note, a, d, s, r, timeFromNow) { + p5.PolySynth.prototype.noteADSR = function (note, a, d, s, r) { + var timeFromNow = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; var now = p5sound.audiocontext.currentTime; - var timeFromNow = timeFromNow || 0; var t = now + timeFromNow; this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r); }; @@ -2674,47 +2795,52 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) { - var secondsFromNow = ~~secondsFromNow; - - var acTime = p5sound.audiocontext.currentTime + secondsFromNow; + p5.PolySynth.prototype.noteAttack = function (_note, _velocity) { + var secondsFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + //this value is used by this._voicesInUse + var acTime = p5sound.audiocontext.currentTime + secondsFromNow; //Convert note to frequency if necessary. This is because entries into this.notes + //should be based on frequency for the sake of consistency. var note = noteToFreq(_note); var velocity = _velocity || 0.1; - var currentVoice; + var currentVoice; //Release the note if it is already playing if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) { this.noteRelease(note, 0); - } + } //Check to see how many voices are in use at the time the note will start if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) { currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0); - } + } //If we are exceeding the polyvalue, bump off the oldest notes and replace + //with a new note else { currentVoice = this._oldest; var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value); this.noteRelease(oldestNote); this._oldest = (this._oldest + 1) % (this.maxVoices - 1); - } + } //Overrite the entry in the notes object. A note (frequency value) + //corresponds to the index of the audiovoice that is playing it this.notes[note] = new TimelineSignal(); - this.notes[note].setValueAtTime(currentVoice, acTime); + this.notes[note].setValueAtTime(currentVoice, acTime); //Find the scheduled change in this._voicesInUse that will be previous to this new note + //Add 1 and schedule this value at time 't', when this note will start playing var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value; - this._voicesInUse.setValueAtTime(previousVal + 1, acTime); + this._voicesInUse.setValueAtTime(previousVal + 1, acTime); //Then update all scheduled values that follow to increase by 1 this._updateAfter(acTime, 1); - this._newest = currentVoice; + this._newest = currentVoice; //The audiovoice handles the actual scheduling of the note if (typeof velocity === 'number') { var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2; velocity = velocity > maxRange ? maxRange : velocity; - } + } // use secondsFromNow because this method will add AudioContext currentTime + this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow); }; @@ -2788,7 +2914,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.PolySynth.prototype.noteRelease = function (_note, secondsFromNow) { var now = p5sound.audiocontext.currentTime; var tFromNow = secondsFromNow || 0; - var t = now + tFromNow; + var t = now + tFromNow; // if a note value is not provided, release all voices if (!_note) { this.audiovoices.forEach(function (voice) { @@ -2803,7 +2929,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } return; - } + } //Make sure note is in frequency inorder to query the this.notes object var note = noteToFreq(_note); @@ -2811,9 +2937,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) { console.warn('Cannot release a note that is not already playing'); } else { + //Find the scheduled change in this._voicesInUse that will be previous to this new note + //subtract 1 and schedule this value at time 't', when this note will stop playing var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1); - this._voicesInUse.setValueAtTime(previousVal - 1, t); + this._voicesInUse.setValueAtTime(previousVal - 1, t); //Then update all scheduled values that follow to decrease by 1 but never go below 0 if (previousVal > 0) { @@ -2827,12 +2955,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } }; /** - * Connect to a p5.sound / Web Audio object. - * - * @method connect - * @for p5.PolySynth - * @param {Object} unit A p5.sound or Web Audio object - */ + * Connect to a p5.sound / Web Audio object. + * + * @method connect + * @for p5.PolySynth + * @param {Object} unit A p5.sound or Web Audio object + */ p5.PolySynth.prototype.connect = function (unit) { @@ -2840,11 +2968,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.output.connect(u.input ? u.input : u); }; /** - * Disconnect all outputs - * - * @method disconnect - * @for p5.PolySynth - */ + * Disconnect all outputs + * + * @method disconnect + * @for p5.PolySynth + */ p5.PolySynth.prototype.disconnect = function () { @@ -2853,11 +2981,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } }; /** - * Get rid of the MonoSynth and free up its resources / memory. - * - * @method dispose - * @for p5.PolySynth - */ + * Get rid of the MonoSynth and free up its resources / memory. + * + * @method dispose + * @for p5.PolySynth + */ p5.PolySynth.prototype.dispose = function () { @@ -2873,8 +3001,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -2890,7 +3019,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; __webpack_require__(6); - __webpack_require__(11); + __webpack_require__(12); __webpack_require__(36); @@ -2956,13 +3085,15 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports) { +/***/ }), +/* 32 */ +/***/ (function(module, exports) { !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= 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; 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);"); +/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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; 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);"); - }), - (function(module, __webpack_exports__, __webpack_require__) { +/***/ }), +/* 38 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); - __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, [{\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; ++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);"); +/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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);"); - }), - (function(module, __webpack_exports__, __webpack_require__) { +/***/ }), +/* 39 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); - __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, [{\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; ++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; 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);"); +/* harmony default export */ __webpack_exports__["default"] = ("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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; 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);"); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; -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); } - !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { var p5sound = __webpack_require__(1); - var ac = p5sound.audiocontext; + var ac = p5sound.audiocontext; // Stereo panner + // if there is a stereo panner node use it if (typeof ac.createStereoPanner !== 'undefined') { p5.Panner = function (input, output) { @@ -3256,7 +3406,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var time = tFromNow || 0; var t = ac.currentTime + time; this.stereoPanner.pan.linearRampToValueAtTime(val, t); - }; + }; //not implemented because stereopanner + //node does not require this and will automatically + //convert single channel or multichannel to stereo. + //tested with single and stereo, not with (>2) multichannel p5.Panner.prototype.inputChannels = function () {}; @@ -3271,13 +3424,16 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } }; } else { + // if there is no createStereoPanner object + // such as in safari 7.1.7 at the time of writing this + // use this method to create the effect p5.Panner = function (input, output, numInputChannels) { this.input = ac.createGain(); input.connect(this.input); this.left = ac.createGain(); this.right = ac.createGain(); this.left.channelInterpretation = 'discrete'; - this.right.channelInterpretation = 'discrete'; + this.right.channelInterpretation = 'discrete'; // if input is stereo if (numInputChannels > 1) { this.splitter = ac.createChannelSplitter(2); @@ -3293,7 +3449,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this.left.connect(this.output, 0, 1); this.right.connect(this.output, 0, 0); this.output.connect(output); - }; + }; // -1 is left, +1 is right p5.Panner.prototype.pan = function (val, tFromNow) { @@ -3312,7 +3468,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this.input.connect(this.left); this.input.connect(this.right); } else if (numChannels === 2) { - if (_typeof(this.splitter === 'undefined')) { + if (typeof this.splitter === 'undefined') { this.splitter = ac.createChannelSplitter(2); } @@ -3336,8 +3492,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -3345,7 +3502,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; 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); } !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var CustomError = __webpack_require__(11); + var CustomError = __webpack_require__(12); var p5sound = __webpack_require__(1); @@ -3424,9 +3581,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this.url = path; } else if (_typeof(paths) === 'object') { if (!(window.File && window.FileReader && window.FileList && window.Blob)) { + // The File API isn't supported in this browser throw 'Unable to load file because the File API is not supported'; } - } + } // if type is a p5.File...get the actual file if (paths.file) { @@ -3434,7 +3592,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } this.file = paths; - } + } // private _onended callback, set by the method: onended(callback) this._onended = function () {}; @@ -3442,38 +3600,38 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this._looping = false; this._playing = false; this._paused = false; - this._pauseTime = 0; + this._pauseTime = 0; // cues for scheduling events with addCue() removeCue() this._cues = []; - this._cueIDCounter = 0; + this._cueIDCounter = 0; // position of the most recently played sample this._lastPos = 0; this._counterNode = null; - this._workletNode = null; + this._workletNode = null; // array of sources so that they can all be stopped! - this.bufferSourceNodes = []; + this.bufferSourceNodes = []; // current source this.bufferSourceNode = null; this.buffer = null; this.playbackRate = 1; this.input = p5sound.audiocontext.createGain(); this.output = p5sound.audiocontext.createGain(); - this.reversed = false; + this.reversed = false; // start and end of playback / loop this.startTime = 0; this.endTime = null; - this.pauseTime = 0; + this.pauseTime = 0; // "restart" would stop playback before retriggering - this.mode = 'sustain'; + this.mode = 'sustain'; // time that playback was started, in millis - this.startMillis = null; + this.startMillis = null; // stereo panning this.panPosition = 0.0; - this.panner = new p5.Panner(this.output, p5sound.input, 2); + this.panner = new p5.Panner(this.output, p5sound.input, 2); // it is possible to instantiate a soundfile with no path if (this.url || this.file) { this.load(onload, onerror); - } + } // add this p5.SoundFile to the soundArray p5sound.soundArray.push(this); @@ -3485,7 +3643,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } this._clearOnEnd = _clearOnEnd.bind(this); - }; + }; // register preload handling of loadSound p5.prototype.registerPreloadMethod('loadSound', p5.prototype); @@ -3536,6 +3694,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat */ p5.prototype.loadSound = function (path, callback, onerror, whileLoading) { + // if loading locally without a server if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); } @@ -3578,8 +3737,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat request.onload = function () { if (request.status === 200) { + // on sucess loading file: if (!self.panner) return; - ac.decodeAudioData(request.response, + ac.decodeAudioData(request.response, // success decoding buffer: function (buff) { if (!self.panner) return; self.buffer = buff; @@ -3588,7 +3748,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat if (callback) { callback(self); } - }, + }, // error decoding buffer. "e" is undefined in Chrome 11/22/2015 function () { if (!self.panner) return; var err = new CustomError('decodeAudioData', errorTrace, self.url); @@ -3601,7 +3761,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat console.error(msg + '\n The error stack trace includes: \n' + err.stack); } }); - } + } // if request status != 200, it failed else { if (!self.panner) return; var err = new CustomError('loadSound', errorTrace, self.url); @@ -3614,7 +3774,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat console.error(msg + '\n The error stack trace includes: \n' + err.stack); } } - }; + }; // if there is another error, aside from 404... request.onerror = function () { @@ -3656,16 +3816,17 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat reader.readAsArrayBuffer(this.file); } - }; + }; // TO DO: use this method to create a loading bar that shows progress during file upload/decode. p5.SoundFile.prototype._updateProgress = function (evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total * 0.99; - this._whileLoading(percentComplete, evt); + this._whileLoading(percentComplete, evt); // ... } else { + // Unable to compute progress information since the total size is unknown this._whileLoading('size unknown'); } }; @@ -3721,31 +3882,33 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat if (typeof amp !== 'undefined') { this.setVolume(amp); - } + } // TO DO: if already playing, create array of buffers for easy stop() if (this.buffer) { - this._pauseTime = 0; + // reset the pause time (if it was paused) + this._pauseTime = 0; // handle restart playmode if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) { this.bufferSourceNode.stop(time); this._counterNode.stop(time); - } + } //dont create another instance if already playing if (this.mode === 'untildone' && this.isPlaying()) { return; - } + } // make a new source and counter. They are automatically assigned playbackRate and buffer - this.bufferSourceNode = this._initSourceNode(); + this.bufferSourceNode = this._initSourceNode(); // garbage collect counterNode and create a new one delete this._counterNode; this._counterNode = this._initCounterNode(); if (_cueStart) { if (_cueStart >= 0 && _cueStart < this.buffer.duration) { + // this.startTime = cueStart; cueStart = _cueStart; } else { throw 'start time out of range'; @@ -3755,8 +3918,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } if (duration) { + // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration; - } + } // if it was paused, play at the pause position if (this._paused) { @@ -3770,15 +3934,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } this._playing = true; - this._paused = false; + this._paused = false; // add source to sources array, which is used in stopAll() this.bufferSourceNodes.push(this.bufferSourceNode); this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1; this.bufferSourceNode.addEventListener('ended', this._clearOnEnd); - } + } // If soundFile hasn't loaded the buffer yet, throw an error else { throw 'not ready to play file, buffer has yet to load. Try preload()'; - } + } // if looping, will restart at original time this.bufferSourceNode.loop = this._looping; @@ -3835,14 +3999,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat p5.SoundFile.prototype.playMode = function (str) { - var s = str.toLowerCase(); + var s = str.toLowerCase(); // if restart, stop all other sounds from playing if (s === 'restart' && this.buffer && this.bufferSourceNode) { for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) { var now = p5sound.audiocontext.currentTime; this.bufferSourceNodes[i].stop(now); } - } + } // set play mode to effect future playback if (s === 'restart' || s === 'sustain' || s === 'untildone') { @@ -3903,7 +4067,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this._counterNode.stop(pTime); - this._pauseTime = this.currentTime(); + this._pauseTime = this.currentTime(); // TO DO: make sure play() still starts from orig start position } else { this._pauseTime = 0; } @@ -4067,10 +4231,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat for (var i in this.bufferSourceNodes) { var bufferSourceNode = this.bufferSourceNodes[i]; - if (!!bufferSourceNode) { + if (bufferSourceNode) { try { bufferSourceNode.stop(now + time); - } catch (e) { + } catch (e) {// this was throwing errors only on Safari } } } @@ -4113,12 +4277,13 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } else if (vol) { vol.connect(this.output.gain); } else { + // return the Gain Node return this.output.gain; } - }; + }; // same as setVolume, to match Processing Sound - p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume; + p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume; // these are the same thing p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume; @@ -4261,7 +4426,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } return this.playbackRate; - }; + }; // TO DO: document this p5.SoundFile.prototype.setPitch = function (num) { @@ -4282,6 +4447,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat p5.SoundFile.prototype.duration = function () { + // Return Duration if (this.buffer) { return this.buffer.duration; } else { @@ -4334,38 +4500,38 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } }; /** - * Return the number of channels in a sound file. - * For example, Mono = 1, Stereo = 2. - * - * @method channels - * @for p5.SoundFile - * @return {Number} [channels] - */ + * Return the number of channels in a sound file. + * For example, Mono = 1, Stereo = 2. + * + * @method channels + * @for p5.SoundFile + * @return {Number} [channels] + */ p5.SoundFile.prototype.channels = function () { return this.buffer.numberOfChannels; }; /** - * Return the sample rate of the sound file. - * - * @method sampleRate - * @for p5.SoundFile - * @return {Number} [sampleRate] - */ + * Return the sample rate of the sound file. + * + * @method sampleRate + * @for p5.SoundFile + * @return {Number} [sampleRate] + */ p5.SoundFile.prototype.sampleRate = function () { return this.buffer.sampleRate; }; /** - * Return the number of samples in a sound file. - * Equal to sampleRate * duration. - * - * @method frames - * @for p5.SoundFile - * @return {Number} [sampleCount] - */ + * Return the number of samples in a sound file. + * Equal to sampleRate * duration. + * + * @method frames + * @for p5.SoundFile + * @return {Number} [sampleCount] + */ p5.SoundFile.prototype.frames = function () { @@ -4391,6 +4557,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat p5.SoundFile.prototype.getPeaks = function (length) { if (this.buffer) { + // set length to window's width if no length is provided if (!length) { length = window.width * 5; } @@ -4414,7 +4581,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var value = chan[j]; if (value > max) { - max = value; + max = value; // faster than Math.abs } else if (-value > max) { max = value; } @@ -4471,7 +4638,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat for (var i = 0; i < numChannels; i++) { this.buffer.getChannelData(i).reverse(); - } + } // set reversed flag this.reversed = !this.reversed; @@ -4504,11 +4671,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat return this; }; - p5.SoundFile.prototype.add = function () { + p5.SoundFile.prototype.add = function () {// TO DO }; p5.SoundFile.prototype.dispose = function () { - var now = p5sound.audiocontext.currentTime; + var now = p5sound.audiocontext.currentTime; // remove reference to soundfile var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -4636,10 +4803,16 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat channel.set(buf[channelNum]); } - this.buffer = newBuffer; + this.buffer = newBuffer; // set numbers of channels on input to the panner this.panner.inputChannels(numChannels); - }; + }; ////////////////////////////////////////////////// + // script processor node with an empty buffer to help + // keep a sample-accurate position in playback buffer. + // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV + // Copyright [2015] [Sonoport (Asia) Pte. Ltd.], + // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0 + //////////////////////////////////////////////////////////////////////////////////// var _createCounterBuffer = function _createCounterBuffer(buffer) { @@ -4652,7 +4825,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } return audioBuf; - }; + }; // initialize counterNode, set its initial buffer and playbackRate p5.SoundFile.prototype._initCounterNode = function () { @@ -4661,7 +4834,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var self = this; var now = ac.currentTime; var cNode = ac.createBufferSource(); - var workletBufferSize = safeBufferSize(256); + var workletBufferSize = safeBufferSize(256); // dispose of worklet node if it already exists if (self._workletNode) { self._workletNode.disconnect(); @@ -4677,15 +4850,16 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat self._workletNode.port.onmessage = function (event) { if (event.data.name === 'position') { + // event.data.position should only be 0 when paused if (event.data.position === 0) { return; } - _this._lastPos = event.data.position; + _this._lastPos = event.data.position; // do any callbacks that have been scheduled _this._onTimeUpdate(self._lastPos); } - }; + }; // create counter buffer of the same length as self.buffer cNode.buffer = _createCounterBuffer(self.buffer); @@ -4695,7 +4869,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat self._workletNode.connect(p5.soundOut._silentNode); return cNode; - }; + }; // initialize sourceNode, set its initial buffer and playbackRate p5.SoundFile.prototype._initSourceNode = function () { @@ -4733,47 +4907,51 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var initialThreshold = _initThreshold || 0.9, threshold = initialThreshold, minThreshold = _minThreshold || 0.22, - minPeaks = _minPeaks || 200; + minPeaks = _minPeaks || 200; // Create offline context - var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate); + var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate); // create buffer source var source = offlineContext.createBufferSource(); - source.buffer = buffer; + source.buffer = buffer; // Create filter. TO DO: allow custom setting of filter var filter = offlineContext.createBiquadFilter(); filter.type = 'lowpass'; source.connect(filter); - filter.connect(offlineContext.destination); + filter.connect(offlineContext.destination); // start playing at time:0 source.start(0); - offlineContext.startRendering(); + offlineContext.startRendering(); // Render the song + // act on the result offlineContext.oncomplete = function (e) { if (!self.panner) return; var filteredBuffer = e.renderedBuffer; - var bufferData = filteredBuffer.getChannelData(0); + var bufferData = filteredBuffer.getChannelData(0); // step 1: + // create Peak instances, add them to array, with strength and sampleIndex do { allPeaks = getPeaksAtThreshold(bufferData, threshold); threshold -= 0.005; - } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold); + } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold); // step 2: + // find intervals for each peak in the sampleIndex, add tempos array - var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks); + var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks); // step 3: find top tempos - var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate); + var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate); // sort top intervals var topTempos = groups.sort(function (intA, intB) { return intB.count - intA.count; - }).splice(0, 5); + }).splice(0, 5); // set this SoundFile's tempo to the top tempo ?? - this.tempo = topTempos[0].tempo; + this.tempo = topTempos[0].tempo; // step 4: + // new array of peaks at top tempo within a bpmVariance var bpmVariance = 5; var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance); callback(tempoPeaks); }; - }; + }; // process peaks var Peak = function Peak(amp, i) { @@ -4781,7 +4959,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat this.amplitude = amp; this.tempos = []; this.intervals = []; - }; + }; // 1. for processPeaks() Function to identify peaks above a threshold + // returns an array of peak indexes as frames (samples) of the original soundfile function getPeaksAtThreshold(data, threshold) { @@ -4792,7 +4971,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat if (data[i] > threshold) { var amp = data[i]; var peak = new Peak(amp, i); - peaksObj[i] = peak; + peaksObj[i] = peak; // Skip forward ~ 1/8s to get past this peak. i += 6000; } @@ -4801,7 +4980,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } return peaksObj; - } + } // 2. for processPeaks() function countIntervalsBetweenNearbyPeaks(peaksObj) { @@ -4809,6 +4988,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var peaksArray = Object.keys(peaksObj).sort(); for (var index = 0; index < peaksArray.length; index++) { + // find intervals in comparison to nearby peaks for (var i = 0; i < 10; i++) { var startPeak = peaksObj[peaksArray[index]]; var endPeak = peaksObj[peaksArray[index + i]]; @@ -4816,11 +4996,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat if (startPeak && endPeak) { var startPos = startPeak.sampleIndex; var endPos = endPeak.sampleIndex; - var interval = endPos - startPos; + var interval = endPos - startPos; // add a sample interval to the startPeak in the allPeaks array if (interval > 0) { startPeak.intervals.push(interval); - } + } // tally the intervals and return interval counts var foundInterval = intervalCounts.some(function (intervalCount) { @@ -4828,7 +5008,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat intervalCount.count++; return intervalCount; } - }); + }); // store with JSON like formatting if (!foundInterval) { intervalCounts.push({ @@ -4841,13 +5021,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } return intervalCounts; - } + } // 3. for processPeaks --> find tempo function groupNeighborsByTempo(intervalCounts, sampleRate) { var tempoCounts = []; intervalCounts.forEach(function (intervalCount) { try { + // Convert an interval to tempo var theoreticalTempo = Math.abs(60 / (intervalCount.interval / sampleRate)); theoreticalTempo = mapTempo(theoreticalTempo); var foundTempo = tempoCounts.some(function (tempoCount) { @@ -4869,12 +5050,12 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } }); return tempoCounts; - } + } // 4. for processPeaks - get peaks at top tempo function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) { var peaksAtTopTempo = []; - var peaksArray = Object.keys(peaksObj).sort(); + var peaksArray = Object.keys(peaksObj).sort(); // TO DO: filter out peaks that have the tempo and return for (var i = 0; i < peaksArray.length; i++) { var key = peaksArray[i]; @@ -4885,10 +5066,11 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat intervalBPM = mapTempo(intervalBPM); if (Math.abs(intervalBPM - tempo) < bpmVariance) { + // convert sampleIndex to seconds peaksAtTopTempo.push(peak.sampleIndex / sampleRate); } } - } + } // filter out peaks that are very close to each other peaksAtTopTempo = peaksAtTopTempo.filter(function (peakTime, index, arr) { @@ -4899,13 +5081,14 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } }); return peaksAtTopTempo; - } + } // helper function for processPeaks function mapTempo(theoreticalTempo) { + // these scenarios create infinite while loop if (!isFinite(theoreticalTempo) || theoreticalTempo === 0) { return; - } + } // Adjust the tempo to fit within the 90-180 BPM range while (theoreticalTempo < 90) { @@ -4918,6 +5101,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat return theoreticalTempo; } + /*** SCHEDULE EVENTS ***/ + // Cue inspired by JavaScript setTimeout, and the + // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org var Cue = function Cue(callback, time, id, val) { @@ -4991,7 +5177,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var id = this._cueIDCounter++; var cue = new Cue(callback, time, id, val); - this._cues.push(cue); + this._cues.push(cue); // if (!this.elt.ontimeupdate) { + // this.elt.ontimeupdate = this._onTimeUpdate.bind(this); + // } return id; @@ -5019,7 +5207,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat } } - if (this._cues.length === 0) { + if (this._cues.length === 0) {// TO DO: remove callback + // this.elt.ontimeupdate = null } }; /** @@ -5031,8 +5220,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat p5.SoundFile.prototype.clearCues = function () { - this._cues = []; - }; + this._cues = []; // this.elt.ontimeupdate = null; + }; // private method that checks for cues to be fired if events + // have been scheduled using addCue(callback, time). p5.SoundFile.prototype._onTimeUpdate = function (position) { @@ -5045,6 +5235,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat var val = cue.val; if (~~this._prevUpdateTime <= callbackTime && callbackTime <= playbackTime) { + // pass the scheduled callbackTime as parameter to the callback cue.callback(val); } } @@ -5054,7 +5245,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat /** * Save a p5.SoundFile as a .wav file. The browser will prompt the user * to download the file to their device. To upload a file to a server, see - * getBlob + * getBlob * * @method save * @for p5.SoundFile @@ -5087,7 +5278,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat * .wav-encoded audio data as a "Blob". * A Blob is a file-like data object that can be uploaded to a server - * with an http request. We'll + * with an http request. We'll * use the `httpDo` options object to send a POST request with some * specific options: we encode the request as `multipart/form-data`, * and attach the blob as one of the form values using `FormData`. @@ -5140,17 +5331,18 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat return new Blob([dataView], { type: 'audio/wav' }); - }; + }; // event handler to remove references to the bufferSourceNode when it is done playing function _clearOnEnd(e) { var thisBufferSourceNode = e.target; - var soundFile = this; + var soundFile = this; // delete this.bufferSourceNode from the sources array when it is done playing: thisBufferSourceNode._playing = false; - thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd); + thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd); // call the onended callback - soundFile._onended(soundFile); + soundFile._onended(soundFile); // delete bufferSourceNode(s) in soundFile.bufferSourceNodes + // iterate in reverse order because the index changes by splice soundFile.bufferSourceNodes.map(function (_, i) { @@ -5170,8 +5362,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -5228,7 +5421,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Amplitude = function (smoothing) { - this.bufferSize = safeBufferSize(2048); + // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default + this.bufferSize = safeBufferSize(2048); // set audio context this.audiocontext = p5sound.audiocontext; this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, { @@ -5251,11 +5445,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.stereoVol = event.data.stereoVol; this.stereoVolNorm = event.data.stereoVolNorm; } - }.bind(this); + }.bind(this); // for connections this.input = this._workletNode; - this.output = this.audiocontext.createGain(); + this.output = this.audiocontext.createGain(); // the variables to return this.volume = 0; this.volNorm = 0; @@ -5265,11 +5459,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this._workletNode.connect(this.output); - this.output.gain.value = 0; + this.output.gain.value = 0; // this may only be necessary because of a Chrome bug - this.output.connect(this.audiocontext.destination); + this.output.connect(this.audiocontext.destination); // connect to p5sound master output by default, unless set by input() - p5sound.meter.connect(this._workletNode); + p5sound.meter.connect(this._workletNode); // add this p5.SoundFile to the soundArray p5sound.soundArray.push(this); }; @@ -5325,23 +5519,23 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (smoothing) { this._workletNode.parameters.get('smoothing').value = smoothing; - } + } // connect to the master out of p5s instance if no snd is provided if (source == null) { console.log('Amplitude input source is not ready! Connecting to master output instead'); p5sound.meter.connect(this._workletNode); - } + } // if it is a p5.Signal else if (source instanceof p5.Signal) { source.output.connect(this._workletNode); - } + } // connect to the sound if it is available else if (source) { source.connect(this._workletNode); this._workletNode.disconnect(); this._workletNode.connect(this.output); - } + } // otherwise, connect to the master out of p5s instance (default) else { p5sound.meter.connect(this._workletNode); } @@ -5468,6 +5662,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Amplitude.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -5488,8 +5683,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -5605,20 +5801,20 @@ var __WEBPACK_AMD_DEFINE_RESULT__; configurable: true, enumerable: true } - }); + }); // set default smoothing and bins this.smooth(smoothing); - this.bins = bins || 1024; + this.bins = bins || 1024; // default connections to p5sound fftMeter p5sound.fftMeter.connect(this.analyser); this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount); - this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount); + this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount); // predefined frequency ranges, these will be tweakable this.bass = [20, 140]; this.lowMid = [140, 400]; this.mid = [400, 2600]; this.highMid = [2600, 5200]; - this.treble = [5200, 14000]; + this.treble = [5200, 14000]; // add this p5.SoundFile to the soundArray p5sound.soundArray.push(this); }; @@ -5665,7 +5861,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.FFT.prototype.waveform = function () { - var bins, mode, normalArray; + var bins, mode; + var normalArray = new Array(); for (var i = 0; i < arguments.length; i++) { if (typeof arguments[i] === 'number') { @@ -5676,7 +5873,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (typeof arguments[i] === 'string') { mode = arguments[i]; } - } + } // getFloatFrequencyData doesnt work in Safari as of 5/2015 if (mode && !p5.prototype._isSafari()) { @@ -5686,7 +5883,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } else { timeToInt(this, this.timeDomain); this.analyser.getByteTimeDomainData(this.timeDomain); - var normalArray = new Array(); for (var j = 0; j < this.timeDomain.length; j++) { var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1); @@ -5846,9 +6042,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (typeof frequency1 !== 'number') { throw 'invalid input for getEnergy()'; } else if (!frequency2) { + // if only one parameter: var index = Math.round(frequency1 / nyquist * this.freqDomain.length); return this.freqDomain[index]; } else if (frequency1 && frequency2) { + // if two parameters: + // if second is higher than first if (frequency1 > frequency2) { var swap = frequency2; frequency2 = frequency1; @@ -5858,12 +6057,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length); var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length); var total = 0; - var numFrequencies = 0; + var numFrequencies = 0; // add up all of the values for the frequencies for (var i = lowIndex; i <= highIndex; i++) { total += this.freqDomain[i]; numFrequencies += 1; - } + } // divide by total number of frequencies var toReturn = total / numFrequencies; @@ -5871,7 +6070,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } else { throw 'invalid input for getEnergy()'; } - }; + }; // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated... p5.FFT.prototype.getFreq = function (freq1, freq2) { @@ -5889,7 +6088,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * * @method getCentroid * @for p5.FFT - * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz. + * @return {Number} Spectral Centroid Frequency of the spectral centroid in Hz. * * * @example @@ -5983,6 +6182,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.FFT.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -6005,18 +6205,19 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.FFT.prototype.linAverages = function (N) { - var N = N || 16; + p5.FFT.prototype.linAverages = function (_N) { + var N = _N || 16; // This prevents undefined, null or 0 values of N var spectrum = this.freqDomain; var spectrumLength = spectrum.length; var spectrumStep = Math.floor(spectrumLength / N); - var linearAverages = new Array(N); + var linearAverages = new Array(N); // Keep a second index for the current average group and place the values accordingly + // with only one loop in the spectrum data var groupIndex = 0; for (var specIndex = 0; specIndex < spectrumLength; specIndex++) { - linearAverages[groupIndex] = linearAverages[groupIndex] !== undefined ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2 : spectrum[specIndex]; + linearAverages[groupIndex] = linearAverages[groupIndex] !== undefined ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2 : spectrum[specIndex]; // Increase the group index when the last element of the group is processed if (specIndex % spectrumStep === spectrumStep - 1) { groupIndex++; @@ -6044,12 +6245,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var nyquist = p5sound.audiocontext.sampleRate / 2; var spectrum = this.freqDomain; var spectrumLength = spectrum.length; - var logAverages = new Array(octaveBands.length); + var logAverages = new Array(octaveBands.length); // Keep a second index for the current average group and place the values accordingly + // With only one loop in the spectrum data var octaveIndex = 0; for (var specIndex = 0; specIndex < spectrumLength; specIndex++) { - var specIndexFrequency = Math.round(specIndex * nyquist / this.freqDomain.length); + var specIndexFrequency = Math.round(specIndex * nyquist / this.freqDomain.length); // Increase the group index if the current frequency exceeds the limits of the band if (specIndexFrequency > octaveBands[octaveIndex].hi) { octaveIndex++; @@ -6076,10 +6278,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.FFT.prototype.getOctaveBands = function (N, fCtr0) { - var N = N || 3; + p5.FFT.prototype.getOctaveBands = function (_N, _fCtr0) { + var N = _N || 3; // Default to 1/3 Octave Bands - var fCtr0 = fCtr0 || 15.625; + var fCtr0 = _fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz var octaveBands = []; var lastFrequencyBand = { @@ -6100,42 +6302,45 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } return octaveBands; - }; + }; // helper methods to convert type from float (dB) to int (0-255) - var freqToFloat = function freqToFloat(fft) { + function freqToFloat(fft) { if (fft.freqDomain instanceof Float32Array === false) { fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount); } - }; + } - var freqToInt = function freqToInt(fft) { + function freqToInt(fft) { if (fft.freqDomain instanceof Uint8Array === false) { fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount); } - }; + } - var timeToFloat = function timeToFloat(fft) { + function timeToFloat(fft) { if (fft.timeDomain instanceof Float32Array === false) { fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount); } - }; + } - var timeToInt = function timeToInt(fft) { + function timeToInt(fft) { if (fft.timeDomain instanceof Uint8Array === false) { fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount); } - }; + } }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { + // Signal is built with the Tone.js signal by Yotam Mann + // https://github.com/TONEnoTONE/Tone.js/ var Signal = __webpack_require__(2); var Add = __webpack_require__(7); @@ -6147,7 +6352,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; *

p5.Signal is a constant audio-rate signal used by p5.Oscillator * and p5.Envelope for modulation math.

* - *

This is necessary because Web Audio is processed on a seprate clock. + *

This is necessary because Web Audio is processed on a separate clock. * For example, the p5 draw loop runs about 60 times per second. But * the audio clock must process samples 44100 times per second. If we * want to add a value to each of those samples, we can't do it in the @@ -6165,6 +6370,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @example *

* let carrier, modulator; + * let hasStarted = false; * * function setup() { * let cnv = createCanvas(100, 100); @@ -6173,7 +6379,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * text('tap to play', 20, 20); * * carrier = new p5.Oscillator('sine'); - * carrier.start(); * carrier.amp(1); // set amplitude * carrier.freq(220); // set frequency * @@ -6192,6 +6397,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * function canvasPressed() { * userStartAudio(); * carrier.amp(1.0); + * if(!hasStarted){ + * carrier.start(); + * hasStarted = true; + * } * } * * function mouseReleased() { @@ -6202,9 +6411,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Signal = function (value) { - var s = new Signal(value); + var s = new Signal(value); // p5sound.soundArray.push(s); - return s; + return s; // TODO: is this really a constructor? }; /** * Fade to value, for smooth transitions @@ -6235,7 +6444,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; Mult.prototype.setInput = Signal.prototype.setInput; Add.prototype.setInput = Signal.prototype.setInput; - Scale.prototype.setInput = Signal.prototype.setInput; + Scale.prototype.setInput = Signal.prototype.setInput; // signals can add / mult / scale themselves /** * Add a constant value to this audio signal, @@ -6250,7 +6459,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ Signal.prototype.add = function (num) { - var add = new Add(num); + var add = new Add(num); // add.setInput(this); this.connect(add); return add; @@ -6272,7 +6481,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ Signal.prototype.mult = function (num) { - var mult = new Mult(num); + var mult = new Mult(num); // mult.setInput(this); this.connect(mult); return mult; @@ -6319,20 +6528,23 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(21)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(o){o.Frequency=function(e,t){if(!(this instanceof o.Frequency))return new o.Frequency(e,t);o.TimeBase.call(this,e,t)},o.extend(o.Frequency,o.TimeBase),o.Frequency.prototype._primaryExpressions=Object.create(o.TimeBase.prototype._primaryExpressions),o.Frequency.prototype._primaryExpressions.midi={regexp:/^(\d+(?:\.\d+)?midi)/,method:function(e){return this.midiToFrequency(e)}},o.Frequency.prototype._primaryExpressions.note={regexp:/^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,method:function(e,t){var r=n[e.toLowerCase()]+12*(parseInt(t)+1);return this.midiToFrequency(r)}},o.Frequency.prototype._primaryExpressions.tr={regexp:/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/,method:function(e,t,r){var n=1;return e&&"0"!==e&&(n*=this._beatsToUnits(this._timeSignature()*parseFloat(e))),t&&"0"!==t&&(n*=this._beatsToUnits(parseFloat(t))),r&&"0"!==r&&(n*=this._beatsToUnits(parseFloat(r)/4)),n}},o.Frequency.prototype.transpose=function(e){return this._expr=function(e,t){return e()*this.intervalToFrequencyRatio(t)}.bind(this,this._expr,e),this},o.Frequency.prototype.harmonize=function(e){return this._expr=function(e,t){for(var r=e(),n=[],o=0;o + // time constants for simple exponential ramps. + // The larger the time constant value, the slower the + // transition will be. + // + // method _setRampAD + // param {Number} attackTimeConstant attack time constant + // param {Number} decayTimeConstant decay time constant + // p5.Envelope.prototype._setRampAD = function (t1, t2) { this._rampAttackTime = this.checkExpInput(t1); this._rampDecayTime = this.checkExpInput(t2); - var TCDenominator = 1.0; + var TCDenominator = 1.0; /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage) TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)); this._rampAttackTC = t1 / this.checkExpInput(TCDenominator); TCDenominator = Math.log(1.0 / this._rampLowPercentage); this._rampDecayTC = t2 / this.checkExpInput(TCDenominator); - }; + }; // private method p5.Envelope.prototype.setRampPercentages = function (p1, p2) { + //set the percentages that the simple exponential ramps go to this._rampHighPercentage = this.checkExpInput(p1); this._rampLowPercentage = this.checkExpInput(p2); - var TCDenominator = 1.0; + var TCDenominator = 1.0; //now re-compute the time constants based on those percentages + /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage) TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)); this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator); @@ -6695,7 +6928,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Envelope.prototype.setExp = function (isExp) { this.isExponential = isExp; - }; + }; //helper method to protect against zero values being sent to exponential functions p5.Envelope.prototype.checkExpInput = function (value) { @@ -6765,7 +6998,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) { var tFromNow = secondsFromNow || 0; - var susTime = susTime || 0; if (unit) { if (this.connection !== unit) { @@ -6774,7 +7006,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } this.triggerAttack(unit, tFromNow); - this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime); + this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + ~~susTime); }; /** * Trigger the Attack, and Decay portion of the Envelope. @@ -6843,7 +7075,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (this.connection !== unit) { this.connect(unit); } - } + } // get and set value (with linear ramp) to anchor automation var valToSet = this.control.getValueAtTime(t); @@ -6852,7 +7084,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t); } else { this.control.linearRampToValueAtTime(valToSet, t); - } + } // after each ramp completes, cancel scheduled values + // (so they can be overridden in case env has been re-triggered) + // then, set current value (with linearRamp to avoid click) + // then, schedule the next automation... + // attack t += this.aTime; @@ -6867,7 +7103,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; valToSet = this.control.getValueAtTime(t); this.control.cancelScheduledValues(t); this.control.linearRampToValueAtTime(valToSet, t); - } + } // decay to decay level (if using ADSR, then decay level == sustain level) t += this.dTime; @@ -6938,7 +7174,15 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Envelope.prototype.triggerRelease = function (unit, secondsFromNow) { + // only trigger a release if an attack was triggered if (!this.wasTriggered) { + // this currently causes a bit of trouble: + // if a later release has been scheduled (via the play function) + // a new earlier release won't interrupt it, because + // this.wasTriggered has already been set to false. + // If we want new earlier releases to override, then we need to + // keep track of the last release time, and if the new release time is + // earlier, then use it. return; } @@ -6950,7 +7194,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (this.connection !== unit) { this.connect(unit); } - } + } // get and set value (with linear or exponential ramp) to anchor automation var valToSet = this.control.getValueAtTime(t); @@ -6959,7 +7203,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t); } else { this.control.linearRampToValueAtTime(valToSet, t); - } + } // release t += this.rTime; @@ -6991,7 +7235,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @param {Object} unit p5.sound Object or Web Audio Param * @param {Number} secondsFromNow When to trigger the ramp * @param {Number} v Target value - * @param {Number} [v2] Second target value (optional) + * @param {Number} [v2] Second target value * @example *
* let env, osc, amp; @@ -7037,45 +7281,48 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var tFromNow = secondsFromNow || 0; var t = now + tFromNow; var destination1 = this.checkExpInput(v1); - var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined; + var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined; // connect env to unit if not already connected if (unit) { if (this.connection !== unit) { this.connect(unit); } - } + } //get current value - var currentVal = this.checkExpInput(this.control.getValueAtTime(t)); + var currentVal = this.checkExpInput(this.control.getValueAtTime(t)); // this.control.cancelScheduledValues(t); + //if it's going up if (destination1 > currentVal) { this.control.setTargetAtTime(destination1, t, this._rampAttackTC); t += this._rampAttackTime; - } + } //if it's going down else if (destination1 < currentVal) { this.control.setTargetAtTime(destination1, t, this._rampDecayTC); t += this._rampDecayTime; - } + } // Now the second part of envelope begins - if (destination2 === undefined) return; + if (destination2 === undefined) return; //if it's going up if (destination2 > destination1) { this.control.setTargetAtTime(destination2, t, this._rampAttackTC); - } + } //if it's going down else if (destination2 < destination1) { this.control.setTargetAtTime(destination2, t, this._rampDecayTC); } }; p5.Envelope.prototype.connect = function (unit) { - this.connection = unit; + this.connection = unit; // assume we're talking about output gain + // unless given a different audio param 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) { unit = unit.output.gain; } if (unit instanceof AudioParam) { + //set the initial value unit.setValueAtTime(0, p5sound.audiocontext.currentTime); } @@ -7090,7 +7337,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (this.output) { this.output.disconnect(); } - }; + }; // Signal Math /** * Add a value to the p5.Oscillator's output amplitude, @@ -7151,10 +7398,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var thisChain = this.mathOps.length; var nextChain = this.output; return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale); - }; + }; // get rid of the oscillator p5.Envelope.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); this.disconnect(); @@ -7167,7 +7415,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; for (var i = 1; i < this.mathOps.length; i++) { this.mathOps[i].dispose(); } - }; + }; // Different name for backwards compatibility, replicates p5.Envelope class p5.Env = function (t1, l1, t2, l2, t3, l3) { @@ -7179,8 +7427,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -7236,27 +7485,27 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Pulse = function (freq, w) { - p5.Oscillator.call(this, freq, 'sawtooth'); + p5.Oscillator.call(this, freq, 'sawtooth'); // width of PWM, should be betw 0 to 1.0 - this.w = w || 0; + this.w = w || 0; // create a second oscillator with inverse frequency - this.osc2 = new p5.SawOsc(freq); + this.osc2 = new p5.SawOsc(freq); // create a delay node - this.dNode = p5sound.audiocontext.createDelay(); + this.dNode = p5sound.audiocontext.createDelay(); // dc offset this.dcOffset = createDCOffset(); this.dcGain = p5sound.audiocontext.createGain(); this.dcOffset.connect(this.dcGain); - this.dcGain.connect(this.output); + this.dcGain.connect(this.output); // set delay time based on PWM width this.f = freq || 440; var mW = this.w / this.oscillator.frequency.value; this.dNode.delayTime.value = mW; - this.dcGain.gain.value = 1.7 * (0.5 - this.w); + this.dcGain.gain.value = 1.7 * (0.5 - this.w); // disconnect osc2 and connect it to delay, which is connected to output this.osc2.disconnect(); this.osc2.panner.disconnect(); - this.osc2.amp(-1); + this.osc2.amp(-1); // inverted amplitude this.osc2.output.connect(this.dNode); this.dNode.connect(this.output); @@ -7277,7 +7526,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Pulse.prototype.width = function (w) { if (typeof w === 'number') { if (w <= 1.0 && w >= 0.0) { - this.w = w; + this.w = w; // set delay time based on PWM width + // var mW = map(this.w, 0, 1.0, 0, 1/this.f); var mW = this.w / this.oscillator.frequency.value; this.dNode.delayTime.value = mW; @@ -7305,18 +7555,18 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.oscillator.frequency.setValueAtTime(freq, now); this.oscillator.type = type; this.oscillator.connect(this.output); - this.oscillator.start(t + now); + this.oscillator.start(t + now); // set up osc2 this.osc2.oscillator = p5sound.audiocontext.createOscillator(); this.osc2.oscillator.frequency.setValueAtTime(freq, t + now); this.osc2.oscillator.type = type; this.osc2.oscillator.connect(this.osc2.output); this.osc2.start(t + now); - this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency]; + this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency]; // start dcOffset, too this.dcOffset = createDCOffset(); this.dcOffset.connect(this.dcGain); - this.dcOffset.start(t + now); + this.dcOffset.start(t + now); // if LFO connections depend on these oscillators if (this.mods !== undefined && this.mods.frequency !== undefined) { this.mods.frequency.connect(this.freqNode[0]); @@ -7344,12 +7594,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } }; - p5.Pulse.prototype.freq = function (val, rampTime, tFromNow) { + p5.Pulse.prototype.freq = function (val) { + var rampTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + if (typeof val === 'number') { this.f = val; var now = p5sound.audiocontext.currentTime; - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; var currentFreq = this.oscillator.frequency.value; this.oscillator.frequency.cancelScheduledValues(now); this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow); @@ -7368,7 +7619,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; val.output.connect(this.osc2.oscillator.frequency); this.freqMod = val; } - }; + }; // inspiration: http://webaudiodemos.appspot.com/oscilloscope/ function createDCOffset() { @@ -7388,46 +7639,18 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 49 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var p5sound = __webpack_require__(1); - /** - * Noise is a type of oscillator that generates a buffer with random values. - * - * @class p5.Noise - * @extends p5.Oscillator - * @constructor - * @param {String} type Type of noise can be 'white' (default), - * 'brown' or 'pink'. - */ - + var p5sound = __webpack_require__(1); // generate noise buffers - p5.Noise = function (type) { - var assignType; - p5.Oscillator.call(this); - delete this.f; - delete this.freq; - delete this.oscillator; - if (type === 'brown') { - assignType = _brownNoise; - } else if (type === 'pink') { - assignType = _pinkNoise; - } else { - assignType = _whiteNoise; - } - - this.buffer = assignType; - }; - - p5.Noise.prototype = Object.create(p5.Oscillator.prototype); - - var _whiteNoise = function () { + var _whiteNoiseBuffer = function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); var noiseData = whiteBuffer.getChannelData(0); @@ -7440,7 +7663,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; return whiteBuffer; }(); - var _pinkNoise = function () { + var _pinkNoiseBuffer = function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); var noiseData = pinkBuffer.getChannelData(0); @@ -7451,12 +7674,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var white = Math.random() * 2 - 1; b0 = 0.99886 * b0 + white * 0.0555179; b1 = 0.99332 * b1 + white * 0.0750759; - b2 = 0.96900 * b2 + white * 0.1538520; - b3 = 0.86650 * b3 + white * 0.3104856; - b4 = 0.55000 * b4 + white * 0.5329522; - b5 = -0.7616 * b5 - white * 0.0168980; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; - noiseData[i] *= 0.11; + noiseData[i] *= 0.11; // (roughly) compensate for gain b6 = white * 0.115926; } @@ -7465,7 +7688,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; return pinkBuffer; }(); - var _brownNoise = function () { + var _brownNoiseBuffer = function () { var bufferSize = 2 * p5sound.audiocontext.sampleRate; var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate); var noiseData = brownBuffer.getChannelData(0); @@ -7481,6 +7704,36 @@ var __WEBPACK_AMD_DEFINE_RESULT__; brownBuffer.type = 'brown'; return brownBuffer; }(); + /** + * Noise is a type of oscillator that generates a buffer with random values. + * + * @class p5.Noise + * @extends p5.Oscillator + * @constructor + * @param {String} type Type of noise can be 'white' (default), + * 'brown' or 'pink'. + */ + + + p5.Noise = function (type) { + var assignType; + p5.Oscillator.call(this); + delete this.f; + delete this.freq; + delete this.oscillator; + + if (type === 'brown') { + assignType = _brownNoiseBuffer; + } else if (type === 'pink') { + assignType = _pinkNoiseBuffer; + } else { + assignType = _whiteNoiseBuffer; + } + + this.buffer = assignType; + }; + + p5.Noise.prototype = Object.create(p5.Oscillator.prototype); /** * Set type of noise to 'white', 'pink' or 'brown'. * White is the default. @@ -7489,29 +7742,28 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @param {String} [type] 'white', 'pink' or 'brown' */ - p5.Noise.prototype.setType = function (type) { switch (type) { case 'white': - this.buffer = _whiteNoise; + this.buffer = _whiteNoiseBuffer; break; case 'pink': - this.buffer = _pinkNoise; + this.buffer = _pinkNoiseBuffer; break; case 'brown': - this.buffer = _brownNoise; + this.buffer = _brownNoiseBuffer; break; default: - this.buffer = _whiteNoise; + this.buffer = _whiteNoiseBuffer; } if (this.started) { var now = p5sound.audiocontext.currentTime; this.stop(now); - this.start(now + .01); + this.start(now + 0.01); } }; @@ -7543,7 +7795,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Noise.prototype.dispose = function () { - var now = p5sound.audiocontext.currentTime; + var now = p5sound.audiocontext.currentTime; // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -7569,14 +7821,15 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var p5sound = __webpack_require__(1); + var p5sound = __webpack_require__(1); // an array of input sources p5sound.inputSources = []; @@ -7626,6 +7879,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ p5.AudioIn = function (errorCallback) { + // set up audio input /** * @property {GainNode} input @@ -7670,7 +7924,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) { errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices'); - } + } // add to soundArray so we can dispose on close p5sound.soundArray.push(this); @@ -7702,7 +7956,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (this.stream) { this.stop(); - } + } // set the audio source var audioSource = p5sound.inputSources[self.currentSource]; @@ -7711,7 +7965,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; sampleRate: p5sound.audiocontext.sampleRate, echoCancellation: false } - }; + }; // if developers determine which source to use if (p5sound.inputSources[this.currentSource]) { constraints.audio.deviceId = audioSource.deviceId; @@ -7719,10 +7973,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; window.navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { self.stream = stream; - self.enabled = true; + self.enabled = true; // Wrap a MediaStreamSourceNode around the live input self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream); - self.mediaStream.connect(self.output); + self.mediaStream.connect(self.output); // only send to the Amplitude reader, so we can see it but not hear it. self.amplitude.setInput(self.output); if (successCallback) successCallback(); @@ -7785,7 +8039,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.AudioIn.prototype.disconnect = function () { if (this.output) { - this.output.disconnect(); + this.output.disconnect(); // stay connected to amplitude even if not outputting to p5 this.output.connect(this.amplitude.input); } @@ -7836,10 +8090,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; /** * Returns a list of available input sources. This is a wrapper - * for and it returns a Promise. - * + * for + * MediaDevices.enumerateDevices() - Web APIs | MDN + * and it returns a Promise. * @method getSources * @for p5.AudioIn * @param {Function} [successCallback] This callback function handles the sources when they @@ -7897,9 +8151,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * Set the input source. Accepts a number representing a * position in the array returned by getSources(). * This is only available in browsers that support - * navigator.mediaDevices.enumerateDevices().
+ * + * navigator.mediaDevices.enumerateDevices() * * @method setSource * @for p5.AudioIn @@ -7928,20 +8182,22 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.AudioIn.prototype.setSource = function (num) { if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) { + // set the current source this.currentSource = num; console.log('set source to ', p5sound.inputSources[this.currentSource]); } else { console.log('unable to set input source'); - } + } // restart stream if currently active if (this.stream && this.stream.active) { this.start(); } - }; + }; // private method p5.AudioIn.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); this.stop(); @@ -7960,62 +8216,71 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 51 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(2),__webpack_require__(52),__webpack_require__(58),__webpack_require__(9)], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){"use strict";return i.CrossFade=function(e){this.createInsOuts(2,1),this.a=this.input[0]=new i.Gain,this.b=this.input[1]=new i.Gain,this.fade=new i.Signal(this.defaultArg(e,.5),i.Type.NormalRange),this._equalPowerA=new i.EqualPowerGain,this._equalPowerB=new i.EqualPowerGain,this._invert=new i.Expr("1 - $0"),this.a.connect(this.output),this.b.connect(this.output),this.fade.chain(this._equalPowerB,this.b.gain),this.fade.chain(this._invert,this._equalPowerA,this.a.gain),this._readOnly("fade")},i.extend(i.CrossFade),i.CrossFade.prototype.dispose=function(){return i.prototype.dispose.call(this),this._writable("fade"),this._equalPowerA.dispose(),this._equalPowerA=null,this._equalPowerB.dispose(),this._equalPowerB=null,this.fade.dispose(),this.fade=null,this._invert.dispose(),this._invert=null,this.a.dispose(),this.a=null,this.b.dispose(),this.b=null,this},i.CrossFade}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(7),__webpack_require__(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 - * p5.Filter API, especially `gain` and `freq`. - * Bands are stored in an array, with indices 0 - 3, or 0 - 7 - * @property {Array} bands - * - */ + * The p5.EQ is built with abstracted p5.Filter objects. + * To modify any bands, use methods of the + * p5.Filter API, especially `gain` and `freq`. + * Bands are stored in an array, with indices 0 - 3, or 0 - 7 + * @property {Array} bands + * + */ this.bands = []; var freq, res; @@ -8120,10 +8385,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; for (var i = 0; i < _eqsize; i++) { if (i === _eqsize - 1) { freq = 21000; - res = .01; + res = 0.01; } else if (i === 0) { freq = 100; - res = .1; + res = 0.1; } else if (i === 1) { freq = _eqsize === 3 ? 360 * factor : 360; res = 1; @@ -8153,7 +8418,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.EQ.prototype.process = function (src) { src.connect(this.input); - }; + }; // /** // * Set the frequency and gain of each band in the EQ. This method should be // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ. // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2); @@ -8222,8 +8487,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -8278,6 +8544,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; EQFilter.prototype.dispose = function () { + // remove reference form soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); this.disconnect(); @@ -8288,16 +8555,15 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var p5sound = __webpack_require__(1); - - var Effect = __webpack_require__(4); + var Effect = __webpack_require__(5); /** * Panner3D is based on the @@ -8323,13 +8589,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * "https://developer.mozilla.org/en-US/docs/Web/API/PannerNode"> * Web Audio Spatial Panner Node * - * Properties include - * - panningModel: "equal power" or "HRTF" - * - distanceModel: "linear", "inverse", or "exponential" + * Properties include
+ * [Panning Model](https://www.w3.org/TR/webaudio/#idl-def-PanningModelType) + * : "equal power" or "HRTF"
+ * [DistanceModel](https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType) + * : "linear", "inverse", or "exponential" * * @property {AudioNode} panner * @@ -8575,24 +8839,23 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var p5sound = __webpack_require__(1); - - var Effect = __webpack_require__(4); + var p5sound = __webpack_require__(1); // /** // * listener is a class that can construct both a Spatial Panner - // * and a Spatial Listener. The panner is based on the + // * and a Spatial Listener. The panner is based on the // * Web Audio Spatial Panner Node // * https://www.w3.org/TR/webaudio/#the-listenernode-interface // * This panner is a spatial processing node that allows audio to be positioned - // * and oriented in 3D space. + // * and oriented in 3D space. // * - // * The Listener modifies the properties of the Audio Context Listener. + // * The Listener modifies the properties of the Audio Context Listener. // * Both objects types use the same methods. The default is a spatial panner. // * // * p5.Panner3D - Constructs a Spatial Panner
@@ -8612,7 +8875,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Listener3D = function (type) { this.ac = p5sound.audiocontext; this.listener = this.ac.listener; - }; + }; // /** // * Connect an audio sorce // * @param {Object} src Input source // */ @@ -8620,7 +8883,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Listener3D.prototype.process = function (src) { src.connect(this.input); - }; + }; // /** // * Set the X,Y,Z position of the Panner // * @param {[Number]} xVal // * @param {[Number]} yVal @@ -8635,7 +8898,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.positionY(yVal, time); this.positionZ(zVal, time); return [this.listener.positionX.value, this.listener.positionY.value, this.listener.positionZ.value]; - }; + }; // /** // * Getter and setter methods for position coordinates // * @return {Number} [updated coordinate value] // */ @@ -8681,9 +8944,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } return this.listener.positionZ.value; - }; + }; // cannot define method when class definition is commented + // /** // * Overrides the listener orient() method because Listener has slightly - // * different params. In human terms, Forward vectors are the direction the + // * different params. In human terms, Forward vectors are the direction the // * nose is pointing. Up vectors are the direction of the top of the head. // * // * @method orient @@ -8693,7 +8957,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; // * @param {Number} xValU Up vector X direction // * @param {Number} yValU Up vector Y direction // * @param {Number} zValU Up vector Z direction - // * @param {Number} time + // * @param {Number} time // * @return {Array} All orienation params // */ @@ -8722,7 +8986,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.upY(yValU, time); this.upZ(zValU, time); return [this.listener.upX, this.listener.upY, this.listener.upZ]; - }; + }; // /** // * Getter and setter methods for orient coordinates // * @return {Number} [updated coordinate value] // */ @@ -8816,8 +9080,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -8825,7 +9090,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { var Filter = __webpack_require__(15); - var Effect = __webpack_require__(4); + var Effect = __webpack_require__(5); /** * Delay is an echo effect. It processes an existing sound source, * and outputs a delayed version of that sound. The p5.Delay can @@ -8914,7 +9179,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); - this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); + this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime); // graph routing this.input.connect(this._split); @@ -8929,11 +9194,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); - this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); + this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime); // default routing this.setType(0); - this._maxDelay = this.leftDelay.delayTime.maxValue; + this._maxDelay = this.leftDelay.delayTime.maxValue; // set initial feedback to 0.5 this.feedback(0.5); }; @@ -8992,6 +9257,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Delay.prototype.delayTime = function (t) { + // if t is an audio node... if (typeof t !== 'number') { t.connect(this.leftDelay.delayTime); t.connect(this.rightDelay.delayTime); @@ -9020,6 +9286,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Delay.prototype.feedback = function (f) { + // if f is an audio node... if (f && typeof f !== 'number') { f.connect(this._leftGain.gain); f.connect(this._rightGain.gain); @@ -9028,7 +9295,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } else if (typeof f === 'number') { this._leftGain.gain.value = f; this._rightGain.gain.value = f; - } + } // return value of feedback return this._leftGain.gain.value; @@ -9104,7 +9371,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this._rightFilter.output.connect(this.rightDelay); } - }; + }; // DocBlocks for methods inherited from p5.Effect /** * Set the output level of the delay effect. @@ -9162,16 +9429,17 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var CustomError = __webpack_require__(11); + var CustomError = __webpack_require__(12); - var Effect = __webpack_require__(4); + var Effect = __webpack_require__(5); /** * Reverb adds depth to a sound through a large number of decaying * echoes. It creates the perception that sound is occurring in a @@ -9228,10 +9496,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Reverb = function () { Effect.call(this); - this._initConvolverNode(); + this._initConvolverNode(); // otherwise, Safari distorts - this.input.gain.value = 0.5; + this.input.gain.value = 0.5; // default params this._seconds = 3; this._decay = 2; @@ -9331,7 +9599,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (rebuild) { this._buildImpulse(); } - }; + }; // DocBlocks for methods inherited from p5.Effect /** * Set the output level of the reverb effect. @@ -9392,7 +9660,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; Effect.prototype.dispose.apply(this); this._teardownConvolverNode(); - }; + }; // ======================================================================= + // *** p5.Convolver *** + // ======================================================================= /** *

p5.Convolver extends p5.Reverb. It can emulate the sound of real @@ -9466,7 +9736,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @property {ConvolverNode} convolverNode */ - this._initConvolverNode(); + this._initConvolverNode(); // otherwise, Safari distorts this.input.gain.value = 0.5; @@ -9476,6 +9746,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this._loadBuffer(path, callback, errorCallback); } else { + // parameters this._seconds = 3; this._decay = 2; this._reverse = false; @@ -9537,6 +9808,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ p5.prototype.createConvolver = function (path, callback, errorCallback) { + // if loading locally without a server if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); } @@ -9565,8 +9837,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.Convolver.prototype._loadBuffer = function (path, callback, errorCallback) { - var path = p5.prototype._checkFileFormats(path); + p5.Convolver.prototype._loadBuffer = function (_path, callback, errorCallback) { + var path = p5.prototype._checkFileFormats(_path); var self = this; var errorTrace = new Error().stack; @@ -9577,6 +9849,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; request.onload = function () { if (request.status === 200) { + // on success loading file: ac.decodeAudioData(request.response, function (buff) { var buffer = {}; var chunks = path.split('/'); @@ -9589,7 +9862,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (callback) { callback(buffer); } - }, + }, // error decoding buffer. "e" is undefined in Chrome 11/22/2015 function () { var err = new CustomError('decodeAudioData', errorTrace, self.url); var msg = 'AudioContext error at decodeAudioData for ' + self.url; @@ -9601,7 +9874,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; console.error(msg + '\n The error stack trace includes: \n' + err.stack); } }); - } + } // if request status != 200, it failed else { var err = new CustomError('loadConvolver', errorTrace, self.url); var msg = 'Unable to load ' + self.url + '. The request status was: ' + request.status + ' (' + request.statusText + ')'; @@ -9613,7 +9886,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; console.error(msg + '\n The error stack trace includes: \n' + err.stack); } } - }; + }; // if there is another error, aside from 404... request.onerror = function () { @@ -9704,6 +9977,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ p5.Convolver.prototype.addImpulse = function (path, callback, errorCallback) { + // if loading locally without a server if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); } @@ -9724,6 +9998,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Convolver.prototype.resetImpulse = function (path, callback, errorCallback) { + // if loading locally without a server if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') { alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'); } @@ -9771,7 +10046,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Convolver.prototype.dispose = function () { - p5.Reverb.prototype.dispose.apply(this); + p5.Reverb.prototype.dispose.apply(this); // remove all the Impulse Response buffers for (var i in this.impulses) { if (this.impulses[i]) { @@ -9782,24 +10057,26 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var p5sound = __webpack_require__(1); + var p5sound = __webpack_require__(1); // requires the Tone.js library's Clock (MIT license, Yotam Mann) + // https://github.com/TONEnoTONE/Tone.js/ var Clock = __webpack_require__(27); p5.Metro = function () { this.clock = new Clock({ - 'callback': this.ontick.bind(this) + callback: this.ontick.bind(this) }); this.syncedParts = []; - this.bpm = 120; + this.bpm = 120; // gets overridden by p5.Part this._init(); @@ -9816,12 +10093,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; if (elapsedTime - this.tatumTime <= -0.02) { return; } else { - this.prevTick = tickTime; + // console.log('ok', this.syncedParts[0].phrases[0].name); + this.prevTick = tickTime; // for all of the active things on the metro: var self = this; this.syncedParts.forEach(function (thisPart) { if (!thisPart.isPlaying) return; - thisPart.incrementStep(secondsFromNow); + thisPart.incrementStep(secondsFromNow); // each synced source keeps track of its own beat number thisPart.phrases.forEach(function (thisPhrase) { var phraseArray = thisPhrase.sequence; @@ -9837,11 +10115,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } }; - p5.Metro.prototype.setBPM = function (bpm, rampTime) { + p5.Metro.prototype.setBPM = function (bpm) { + var rampTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var beatTime = 60 / (bpm * this.tatums); var now = p5sound.audiocontext.currentTime; this.tatumTime = beatTime; - var rampTime = rampTime || 0; this.clock.frequency.setValueAtTime(this.clock.frequency.value, now); this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime); this.bpm = bpm; @@ -9852,13 +10130,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Metro.prototype._init = function () { - this.metroTicks = 0; - }; + this.metroTicks = 0; // this.setBPM(120); + }; // clear existing synced parts, add only this one p5.Metro.prototype.resetSync = function (part) { this.syncedParts = [part]; - }; + }; // push a new synced part to the array p5.Metro.prototype.pushSync = function (part) { @@ -9879,19 +10157,21 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Metro.prototype.beatLength = function (tatums) { - this.tatums = 1 / tatums / 4; + this.tatums = 1 / tatums / 4; // lowest possible division of a beat }; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { var __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__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -10055,13 +10335,13 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Part = function (steps, bLength) { - this.length = steps || 0; + this.length = steps || 0; // how many beats this.partStep = 0; this.phrases = []; this.isPlaying = false; this.noLoop(); - this.tatums = bLength || 0.0625; + this.tatums = bLength || 0.0625; // defaults to quarter note this.metro = new p5.Metro(); @@ -10129,7 +10409,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Part.prototype.loop = function (time) { - this.looping = true; + this.looping = true; // rest onended function this.onended = function () { this.partStep = 0; @@ -10147,7 +10427,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Part.prototype.noLoop = function () { - this.looping = false; + this.looping = false; // rest onended function this.onended = function () { this.stop(); @@ -10201,7 +10481,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase'; } - this.phrases.push(p); + this.phrases.push(p); // reset the length if phrase is longer than part's existing length if (p.sequence.length > this.length) { this.length = p.sequence.length; @@ -10266,6 +10546,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.partStep += 1; } else { if (!this.looping && this.partStep === this.length - 1) { + // this.callback(time); this.onended(); } } @@ -10283,7 +10564,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Part.prototype.onStep = function (callback) { this.callback = callback; - }; + }; // =============== + // p5.Score + // =============== /** * A Score consists of a series of Parts. The parts will @@ -10298,6 +10581,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Score = function () { + // for all of the arguments this.parts = []; this.currentPart = 0; var thisScore = this; @@ -10319,6 +10603,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Score.prototype.onended = function () { if (this.looping) { + // this.resetParts(); this.parts[0].start(); } else { this.parts[this.parts.length - 1].onended = function () { @@ -10441,8 +10726,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -10529,7 +10815,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.maxIterations = Infinity; var self = this; this.clock = new Clock({ - 'callback': function callback(time) { + callback: function callback(time) { var timeFromNow = time - p5sound.audiocontext.currentTime; /** * Do not initiate the callback if timeFromNow is < 0 @@ -10543,7 +10829,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; self.callback(timeFromNow); } }, - 'frequency': this._calcFreq() + frequency: this._calcFreq() }); }; /** @@ -10598,7 +10884,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; } }; /** - * Synchronize loops. Use this method to start two more more loops in synchronization + * Synchronize loops. Use this method to start two or more loops in synchronization * or to start a loop in synchronization with a loop that is already playing * This method will schedule the implicit loop in sync with the explicit master loop * i.e. loopToStart.syncedStart(loopToSyncWith) @@ -10646,10 +10932,11 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.SoundLoop.prototype._calcFreq = function () { + //Seconds mode, bpm / timesignature has no effect if (typeof this._interval === 'number') { this.musicalTimeMode = false; return 1 / this._interval; - } + } //Musical timing mode, calculate interval based bpm, interval,and time signature else if (typeof this._interval === 'string') { this.musicalTimeMode = true; return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4); @@ -10756,7 +11043,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; return this._interval; }, set: function set(interval) { - this.musicalTimeMode = typeof interval === 'Number' ? false : true; + this.musicalTimeMode = typeof interval === 'number' ? false : true; this._interval = interval; this._update(); @@ -10778,17 +11065,14 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { 'use strict'; - var p5sound = __webpack_require__(1); - - var Effect = __webpack_require__(4); - - var CustomError = __webpack_require__(11); + var Effect = __webpack_require__(5); /** * Compressor is an audio effect class that performs dynamics compression * on an audio input source. This is a very commonly used technique in music @@ -10816,8 +11100,8 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r Effect.call(this); /** * The p5.Compressor is built with a Web Audio Dynamics Compressor Node - * + * target="_blank" title="W3 spec for Dynamics Compressor Node">Web Audio Dynamics Compressor Node + * * @property {AudioNode} compressor */ @@ -10906,7 +11190,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r p5.Compressor.prototype.attack = function (attack, time) { var t = time || 0; - if (typeof attack == 'number') { + if (typeof attack === 'number') { this.compressor.attack.value = attack; this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t); this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t); @@ -10917,21 +11201,21 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r return this.compressor.attack.value; }; /** - * Get current knee or set value w/ time ramp - * - * @method knee - * @for p5.Compressor - * @param {Number} [knee] A decibel value representing the range above the - * threshold where the curve smoothly transitions to the "ratio" portion. - * default = 30, range 0 - 40 - * @param {Number} [time] Assign time value to schedule the change in value - */ + * Get current knee or set value w/ time ramp + * + * @method knee + * @for p5.Compressor + * @param {Number} [knee] A decibel value representing the range above the + * threshold where the curve smoothly transitions to the "ratio" portion. + * default = 30, range 0 - 40 + * @param {Number} [time] Assign time value to schedule the change in value + */ p5.Compressor.prototype.knee = function (knee, time) { var t = time || 0; - if (typeof knee == 'number') { + if (typeof knee === 'number') { this.compressor.knee.value = knee; this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t); this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t); @@ -10954,7 +11238,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r p5.Compressor.prototype.ratio = function (ratio, time) { var t = time || 0; - if (typeof ratio == 'number') { + if (typeof ratio === 'number') { this.compressor.ratio.value = ratio; this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t); this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t); @@ -10977,7 +11261,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r p5.Compressor.prototype.threshold = function (threshold, time) { var t = time || 0; - if (typeof threshold == 'number') { + if (typeof threshold === 'number') { this.compressor.threshold.value = threshold; this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t); this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t); @@ -11001,7 +11285,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r p5.Compressor.prototype.release = function (release, time) { var t = time || 0; - if (typeof release == 'number') { + if (typeof release === 'number') { this.compressor.release.value = release; this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t); this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t); @@ -11037,13 +11321,15 @@ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = (function (r }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 70 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { + // inspiration: recorder.js, Tone.js & typedarray.org var p5sound = __webpack_require__(1); var _require = __webpack_require__(6), @@ -11132,7 +11418,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.input = ac.createGain(); this.output = ac.createGain(); this._inputChannels = 2; - this._outputChannels = 2; + this._outputChannels = 2; // stereo output, even if input is mono var workletBufferSize = safeBufferSize(1024); this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, { @@ -11157,12 +11443,12 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - this._callback = function () {}; + this._callback = function () {}; // connections this._workletNode.connect(p5.soundOut._silentNode); - this.setInput(); + this.setInput(); // add this p5.SoundFile to the soundArray p5sound.soundArray.push(this); }; @@ -11244,6 +11530,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.SoundRecorder.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -11267,6 +11554,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save * @param {String} fileName name of the resulting .wav file. */ + // add to p5.prototype as this is used by the p5 `save()` method. p5.prototype.saveSound = function (soundFile, fileName) { @@ -11276,8 +11564,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -11375,15 +11664,18 @@ var __WEBPACK_AMD_DEFINE_RESULT__; *

*/ p5.PeakDetect = function (freq1, freq2, threshold, _framesPerPeak) { + // framesPerPeak determines how often to look for a beat. + // If a beat is provided, try to look for a beat based on bpm this.framesPerPeak = _framesPerPeak || 20; this.framesSinceLastPeak = 0; this.decayRate = 0.95; this.threshold = threshold || 0.35; - this.cutoff = 0; + this.cutoff = 0; // how much to increase the cutoff + // TO DO: document this / figure out how to make it accessible this.cutoffMult = 1.5; this.energy = 0; - this.penergy = 0; + this.penergy = 0; // TO DO: document this property / figure out how to make it accessible this.currentValue = 0; /** @@ -11395,7 +11687,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; this.isDetected = false; this.f1 = freq1 || 40; - this.f2 = freq2 || 20000; + this.f2 = freq2 || 20000; // function to call when a peak is detected this._onPeak = function () {}; }; @@ -11415,9 +11707,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; var nrg = this.energy = fftObject.getEnergy(this.f1, this.f2) / 255; if (nrg > this.cutoff && nrg > this.threshold && nrg - this.penergy > 0) { + // trigger callback this._onPeak(); - this.isDetected = true; + this.isDetected = true; // debounce this.cutoff = nrg * this.cutoffMult; this.framesSinceLastPeak = 0; @@ -11510,8 +11803,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; @@ -11590,10 +11884,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__; p5.Gain = function () { this.ac = p5sound.audiocontext; this.input = this.ac.createGain(); - this.output = this.ac.createGain(); + this.output = this.ac.createGain(); // otherwise, Safari distorts this.input.gain.value = 0.5; - this.input.connect(this.output); + this.input.connect(this.output); // add to the soundArray p5sound.soundArray.push(this); }; @@ -11648,9 +11942,9 @@ var __WEBPACK_AMD_DEFINE_RESULT__; */ - p5.Gain.prototype.amp = function (vol, rampTime, tFromNow) { - var rampTime = rampTime || 0; - var tFromNow = tFromNow || 0; + p5.Gain.prototype.amp = function (vol) { + var rampTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var tFromNow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var now = p5sound.audiocontext.currentTime; var currentVol = this.output.gain.value; this.output.gain.cancelScheduledValues(now); @@ -11659,6 +11953,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }; p5.Gain.prototype.dispose = function () { + // remove reference from soundArray var index = p5sound.soundArray.indexOf(this); p5sound.soundArray.splice(index, 1); @@ -11675,14 +11970,18 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }), - (function(module, exports, __webpack_require__) { +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; var __WEBPACK_AMD_DEFINE_RESULT__; !(__WEBPACK_AMD_DEFINE_RESULT__ = (function (require) { - var Effect = __webpack_require__(4); + var Effect = __webpack_require__(5); + /* + * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion) + */ function makeDistortionCurve(amount) { @@ -11830,5 +12129,6 @@ var __WEBPACK_AMD_DEFINE_RESULT__; }).call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - }) - ]); +/***/ }) +/******/ ]); +//# sourceMappingURL=p5.sound.js.map \ No newline at end of file diff --git a/lib/p5.sound.js.map b/lib/p5.sound.js.map index b495f030..6af8a0ca 100644 --- a/lib/p5.sound.js.map +++ b/lib/p5.sound.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///./effect.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./audioWorklet/processorNames.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","prototype","set","params","value","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","i","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","get","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","Object","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","defineProperty","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","call","isBoolean","noOp","_readOnly","property","writable","enumerable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasOwnProperty","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","console","audiocontext","Master","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5sound","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","drywet","fade","u","index","undefined","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","processorNames","freqToMidi","f","mathlog2","m","round","midiToFreq","noteToFreq","note","wholeNotes","A","B","C","D","E","F","G","toUpperCase","octave","slice","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","supported","p","_mathChain","o","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","rightChannel","getChannelData","numberOfChannels","interleaved","interleave","buffer","ArrayBuffer","view","DataView","writeUTFBytes","setUint32","setUint16","lng","volume","setInt16","result","inputIndex","offset","string","setUint8","charCodeAt","safeBufferSize","idealBufferSize","bufferSize","tempAudioWorkletNode","AudioWorkletNode","soundFileProcessor","ScriptProcessorNode","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","module","exports","recorderProcessor","amplitudeProcessor","CustomError","name","errorTrace","failedPath","err","Error","tempStack","splitStack","originalStack","stack","filter","ln","toneConnect","outNum","inNum","nativeConnect","e","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","bind","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","warn","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","startTime","add","endTime","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","t","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","create","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","object","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","n","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","s","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","self","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","DEFAULT_SUSTAIN","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","d","r","timeFromNow","voice","_note","_velocity","acTime","currentVoice","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","parameters","fill","processor","realm","exec","inputBuffer","outputBuffer","$$processors","$$context","createScriptProcessor","outputChannelCount","Map","properties","c","l","defaultValue","MessageChannel","port2","Processor","port","port1","onaudioprocess","$$audioWorklet","AudioWorklet","addModule","fetch","then","ok","status","text","AudioWorkletProcessor","registerProcessor","parameterDescriptors","document","createElement","style","cssText","appendChild","contentWindow","createTextNode","body","$hook","documentElement","transpile","String","fixSetTarget","setTargetValueAtTime","createDelayNode","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","when","noteGrainOn","noteOn","internal_start","noteOff","internal_stop","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","isSupported","canPlayType","isOGGSupported","isMP3Supported","isWAVSupported","isAACSupported","isAIFSupported","g","Function","root","factory","amd","TapListener","element","_dragged","_element","_bindedMove","_moved","_bindedEnd","_ended","isStarted","source","resume","startContext","removeEventListener","promise","Promise","success","checkLoop","requestAnimationFrame","onStarted","tapListeners","bindTapListener","NodeList","querySelectorAll","jquery","toArray","tap","moduleSources","initializedAudioWorklets","loadAudioWorkletModules","all","moduleSrc","objectURL","audioWorklet","preload","_incrementPreload","onWorkletModulesLoad","_decrementPreload","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","mode","startMillis","load","_whileLoading","_clearOnEnd","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","decodeAudioData","response","buff","msg","error","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","chan","currentPos","curVol","onended","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","channel","_createCounterBuffer","audioBuf","arrayBuffer","cNode","workletBufferSize","processorOptions","onmessage","data","_onTimeUpdate","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","initialThreshold","minThreshold","minPeaks","offlineContext","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","intervalCounts","countIntervalsBetweenNearbyPeaks","groups","groupNeighborsByTempo","topTempos","sort","intA","intB","count","tempo","bpmVariance","tempoPeaks","getPeaksAtTopTempo","Peak","sampleIndex","amplitude","tempos","intervals","peaksObj","peak","peaksArray","startPeak","endPeak","startPos","endPos","foundInterval","some","intervalCount","tempoCounts","theoreticalTempo","mapTempo","foundTempo","tempoCount","peaksAtTopTempo","key","intervalBPM","peakTime","dif","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevUpdateTime","save","fileName","saveSound","getBlob","dataView","thisBufferSourceNode","target","soundFile","_","Amplitude","smoothing","parameterData","normalize","volNorm","stereoVol","stereoVolNorm","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","toReturn","freq1","freq2","x","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","spec_centroid_freq","linAverages","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","specIndexFrequency","hi","getOctaveBands","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","Pulse","w","dcOffset","createDCOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","bufferSource","assignType","_brownNoise","_pinkNoise","_whiteNoise","whiteBuffer","noiseData","random","pinkBuffer","b0","b1","b2","b3","b4","b5","b6","white","brownBuffer","lastOut","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","parseArgumentList","parseFunctionCall","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","currentPart","thisScore","nextPart","resetPart","playNextPart","resetParts","scoreStep","aScore","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","numSamples","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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","file":"p5.sound.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *

\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n // Master contains the master sound output.\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *

Scale the output of all sound in this sketch

\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *

How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.

\n *\n *

If no value is provided, returns a Web Audio API Gain Node

\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n // a silent connection to the DesinationNode\n // which will ensure that anything connected to it\n // will not be garbage collected\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5.
\n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * let midiNotes = [60, 64, 67, 72];\n * let noteIndex = 0;\n * let midiVal, freq;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * osc = new p5.TriOsc();\n * env = new p5.Envelope();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 10, 20);\n * if (midiVal) {\n * text('MIDI: ' + midiVal, 10, 40);\n * text('Freq: ' + freq, 10, 60);\n * }\n * }\n *\n * function startSound() {\n * // see also: userStartAudio();\n * osc.start();\n *\n * midiVal = midiNotes[noteIndex % midiNotes.length];\n * freq = midiToFreq(midiVal);\n * osc.freq(freq);\n * env.ramp(osc, 0, 1.0, 0);\n *\n * noteIndex++;\n * }\n *
\n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('sound loaded! tap to play', 10, 20, width - 20);\n * cnv.mousePressed(function() {\n * mySound.play();\n * });\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n function safeBufferSize(idealBufferSize) {\n let bufferSize = idealBufferSize;\n\n // if the AudioWorkletNode is actually a ScriptProcessorNode created via polyfill,\n // make sure that our chosen buffer size isn't smaller than the buffer size automatically\n // selected by the polyfill\n // reference: https://github.com/GoogleChromeLabs/audioworklet-polyfill/issues/13#issuecomment-425014930\n let tempAudioWorkletNode = new AudioWorkletNode(p5sound.audiocontext, processorNames.soundFileProcessor);\n if (tempAudioWorkletNode instanceof ScriptProcessorNode) {\n bufferSize = tempAudioWorkletNode.bufferSize;\n }\n tempAudioWorkletNode.disconnect();\n tempAudioWorkletNode = null;\n\n return bufferSize;\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq,\n safeBufferSize: safeBufferSize\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
    \n\t\t *
  • Numbers, which will be taken literally as the time (in seconds).
  • \n\t\t *
  • Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
  • \n\t\t *
  • TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
  • \n\t\t *
  • Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
  • \n\t\t *
  • Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
  • \n\t\t *
  • Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
  • \n\t\t *
  • No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
  • \n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
    \n\t\t * \t
  • \"4n\" = quarter note
  • \n\t\t * \t
  • \"2m\" = two measures
  • \n\t\t * \t
  • \"8t\" = eighth-note triplet
  • \n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *

A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:

\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff.
\n * p5.HighPass:\n * The opposite of a lowpass filter.
\n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range.
\n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * let fft, noise, filter;\n *\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(makeNoise);\n * fill(255, 0, 255);\n *\n * filter = new p5.BandPass();\n * noise = new p5.Noise();\n * noise.disconnect();\n * noise.connect(filter);\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(220);\n *\n * // set the BandPass frequency based on mouseX\n * let freq = map(mouseX, 0, width, 20, 10000);\n * freq = constrain(freq, 0, 22050);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * let spectrum = fft.analyze();\n * noStroke();\n * for (let i = 0; i < spectrum.length; i++) {\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n * if (!noise.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n * }\n * }\n *\n * function makeNoise() {\n * // see also: `userStartAudio()`\n * noise.start();\n * noise.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * noise.amp(0, 0.2);\n * }\n *\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *

Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .

\n *\n *

Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.

\n *\n * @for p5\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
\n */\n p5.prototype.getAudioContext = function() {\n return audiocontext;\n };\n\n\n /**\n *

It is not only a good practice to give users control over starting\n * audio. This policy is enforced by many web browsers, including iOS and\n * Google Chrome, which create the Web Audio API's\n * Audio Context\n * in a suspended state.

\n *\n *

In these browser-specific policies, sound will not play until a user\n * interaction event (i.e. mousePressed()) explicitly resumes\n * the AudioContext, or starts an audio node. This can be accomplished by\n * calling start() on a p5.Oscillator,\n * play() on a p5.SoundFile, or simply\n * userStartAudio().

\n *\n *

userStartAudio() starts the AudioContext on a user\n * gesture. The default behavior will enable audio on any\n * mouseUp or touchEnd event. It can also be placed in a specific\n * interaction function, such as mousePressed() as in the\n * example below. This method utilizes\n * StartAudioContext\n * , a library by Yotam Mann (MIT Licence, 2016).

\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext\n * has started\n * @return {Promise} Returns a Promise that resolves when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * // mimics the autoplay policy\n * getAudioContext().suspend();\n *\n * let mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has resumed\n * mySynth.play('A6');\n * }\n * function draw() {\n * background(220);\n * textAlign(CENTER, CENTER);\n * text(getAudioContext().state, width/2, height/2);\n * }\n * function mousePressed() {\n * userStartAudio();\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).

\n *\n *

Set the type of oscillation with setType(), or by instantiating a\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\n *

\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * let osc, playing, freq, amp;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator('sine');\n * }\n *\n * function draw() {\n * background(220)\n * freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n * amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n *\n * text('tap to play', 20, 20);\n * text('freq: ' + freq, 20, 40);\n * text('amp: ' + amp, 20, 60);\n *\n * if (playing) {\n * // smooth the transitions by 0.1 seconds\n * osc.freq(freq, 0.1);\n * osc.amp(amp, 0.1);\n * }\n * }\n *\n * function playOscillator() {\n * // starting an oscillator on a user gesture will enable audio\n * // in browsers that have a strict autoplay policy.\n * // See also: userStartAudio();\n * osc.start();\n * playing = true;\n * }\n *\n * function mouseReleased() {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator.\n *\n * Starting an oscillator on a user gesture will enable audio in browsers\n * that have a strict autoplay policy, including Chrome and most mobile\n * devices. See also: `userStartAudio()`.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator(300);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playOscillator() {\n * osc.start();\n * osc.amp(0.5);\n * // start at 700Hz\n * osc.freq(700);\n * // ramp to 60Hz over 0.7 seconds\n * osc.freq(60, 0.7);\n * osc.amp(0, 0.1, 0.7);\n * }\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds.\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this._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; 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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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; 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);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n const CustomError = require('errorHandler');\n const p5sound = require('master');\n const ac = p5sound.audiocontext;\n const { midiToFreq, convertToWav, safeBufferSize } = require('helpers');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *

SoundFile object with a path to a file.

\n *\n *

The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.

\n *\n *

To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.

\n *\n *

Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.

\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * let mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * noFill();\n * rect(0, height/2, width - 1, height/2 - 1);\n * rect(0, 0, width - 1, height/2);\n * textAlign(CENTER, CENTER);\n * fill(20);\n * text('restart', width/2, 1 * height/4);\n * text('sustain', width/2, 3 * height/4);\n * }\n * function canvasPressed() {\n * if (mouseX < height/2) {\n * mySound.playMode('restart');\n * } else {\n * mySound.playMode('sustain');\n * }\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n * let soundFile;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n * @example\n *
\n * let soundFile;\n * let loopStart = 0.5;\n * let loopDuration = 0.2;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n * let ballX = 0;\n * let soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * ballX = constrain(mouseX, 0, width);\n * ellipse(ballX, height/2, 20, 20);\n * }\n *\n * function canvasPressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * let panning = map(ballX, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * let mySound;\n *\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * }\n * function canvasPressed() {\n * mySound.loop();\n * }\n * function mouseReleased() {\n * mySound.pause();\n * }\n * function draw() {\n * background(220);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * let playbackRate = map(mouseY, 0.1, height, 2, 0);\n * playbackRate = constrain(playbackRate, 0.01, 4);\n * mySound.rate(playbackRate);\n *\n * line(0, mouseY, width, mouseY);\n * text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of a soundfile that is currently playing to a\n * new position and a new duration, in seconds.\n * If none are given, will reset the file to play entire duration\n * from start to finish. To set the position of a soundfile that is\n * not currently playing, use the `play` or `loop` methods.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n }\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * let drum;\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function canvasPressed() {\n * drum.stop();\n * drum.reverseBuffer();\n * drum.play();\n * }\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (this.isPlaying() && currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warn('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n const workletBufferSize = safeBufferSize(256);\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor, {\n processorOptions: { bufferSize: workletBufferSize }\n });\n self._workletNode.port.onmessage = event => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 10, 20);\n *\n * // schedule calls to changeText\n * mySound.addCue(0, changeText, \"hello\" );\n * mySound.addCue(0.5, changeText, \"hello,\" );\n * mySound.addCue(1, changeText, \"hello, p5!\");\n * mySound.addCue(1.5, changeText, \"hello, p5!!\");\n * mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n * }\n *\n * function changeText(val) {\n * background(220);\n * text(val, 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (~~this._prevUpdateTime <= callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevUpdateTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to download', 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.save('my cool filename');\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n p5.prototype.saveSound(this, fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * let soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * let httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * let blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n // delete bufferSourceNode(s) in soundFile.bufferSourceNodes\n // iterate in reverse order because the index changes by splice\n soundFile.bufferSourceNodes.map((_, i) => i).reverse().forEach(function (i) {\n const n = soundFile.bufferSourceNodes[i];\n\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i, 1);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const p5sound = require('master');\n const { safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * let sound, amplitude;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = safeBufferSize(2048);\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n\n parameterData: { smoothing: smoothing || 0 },\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0,\n numInputChannels: 2,\n bufferSize: this.bufferSize\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n *\n * amplitude = new p5.Amplitude();\n * amplitude.setInput(sound2);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound1.isPlaying() && sound2.isPlaying()) {\n * sound1.stop();\n * sound2.stop();\n * } else {\n * sound1.play();\n * sound2.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220, 150);\n * textAlign(CENTER);\n * text('tap to play', width/2, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound.isPlaying()) {\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *

FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.

\n *\n *

Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses:
• FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time.
\n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.

\n *\n *

FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.

\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(220);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * let waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(20);\n * for (let i = 0; i < waveform.length; i++){\n * let x = map(i, 0, waveform.length, 0, width);\n * let y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('tap to play', 20, 20);\n * }\n *\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * let osc, fft;\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(startSound);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(220);\n *\n * let freq = map(mouseX, 0, windowWidth, 20, 10000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * if (!osc.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text(round(freq)+'Hz', 10, 20);\n * }\n * }\n *\n * function startSound() {\n * osc.start();\n * osc.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * osc.amp(0, 0.2);\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n\n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.

\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.

\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n * function setup(){\n * cnv = createCanvas(100,100);\n * cnv.mousePressed(userStartAudio);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *function draw() {\n * if (getAudioContext().state !== 'running') {\n * background(220);\n * text('tap here and enable mic to begin', 10, 20, width - 20);\n * return;\n * }\n * let centroidplot = 0.0;\n * let spectralCentroid = 0;\n *\n * background(0);\n * stroke(0,255,0);\n * let spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (let i = 0; i < spectrum.length; i++){\n * let x = map(log(i), 0, log(spectrum.length), 0, width);\n * let h = map(spectrum[i], 0, 255, 0, height);\n * let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n * let nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * let mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text('centroid: ', 10, 20);\n * text(round(spectralCentroid)+' Hz', 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.

\n *\n *

This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.

\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * let carrier, modulator;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * carrier = new p5.Oscillator('sine');\n * carrier.start();\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.start();\n * modulator.amp(1);\n * modulator.freq(4);\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-400).add(220) );\n * }\n *\n * function canvasPressed() {\n * userStartAudio();\n * carrier.amp(1.0);\n * }\n *\n * function mouseReleased() {\n * carrier.amp(0);\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *

Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).

\n *

Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.

\n *

Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.

\n *\n * @class p5.Envelope\n * @constructor\n * @example\n *
\n * let t1 = 0.1; // attack time in seconds\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n *\n * let env;\n * let triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('tap to play', 20, 20);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope(t1, l1, t2, l2);\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function playSound() {\n * // starting the oscillator ensures that audio is enabled.\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * let attackTime;\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n * let l3 = 0.2; // release time in seconds\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n *\n * attackTime = map(mouseX, 0, width, 0.0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 20);\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function playSound() {\n * env.set(attackTime, l1, t2, l2, l3);\n *\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; iPlay tells the envelope to start acting on a given input.\n * If the input is a p5.sound object (i.e. AudioIn, Oscillator,\n * SoundFile), then Envelope will control its output volume.\n * Envelopes can also be used to control any \n * Web Audio Audio Param.

\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * triOsc.start();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * // ensure that audio is enabled\n * userStartAudio();\n *\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * let env, osc, amp;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let attackLevel = 1;\n * let decayLevel = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * // ensures audio is enabled. See also: `userStartAudio`\n * osc.start();\n *\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20);\n * text('tap to play', 10, 20);\n * let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
\n * let pulse;\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startPulse);\n * background(220);\n *\n * pulse = new p5.Pulse();\n * pulse.amp(0.5);\n * pulse.freq(220);\n * }\n * function startPulse() {\n * pulse.start();\n * pulse.amp(0.5, 0.02);\n * }\n * function mouseReleased() {\n * pulse.amp(0, 0.2);\n * }\n * function draw() {\n * background(220);\n * text('tap to play', 5, 20, width - 20);\n * let w = map(mouseX, 0, width, 0, 1);\n * w = constrain(w, 0, 1);\n * pulse.width(w);\n * text('pulse width: ' + w, 5, height - 20);\n * }\n *
\n */\n p5.Pulse = function(freq, w) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n\n // width of PWM, should be betw 0 to 1.0\n this.w = w || 0;\n\n // create a second oscillator with inverse frequency\n this.osc2 = new p5.SawOsc(freq);\n\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n\n // dc offset\n this.dcOffset = createDCOffset();\n this.dcGain = p5sound.audiocontext.createGain();\n this.dcOffset.connect(this.dcGain);\n this.dcGain.connect(this.output);\n // set delay time based on PWM width\n this.f = freq || 440;\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n this.dcGain.gain.value = 1.7*(0.5-this.w);\n\n // disconnect osc2 and connect it to delay, which is connected to output\n this.osc2.disconnect();\n this.osc2.panner.disconnect();\n this.osc2.amp(-1); // inverted amplitude\n this.osc2.output.connect(this.dNode);\n this.dNode.connect(this.output);\n\n this.output.gain.value = 1;\n this.output.connect(this.panner);\n };\n\n p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set the width of a Pulse object (an oscillator that implements\n * Pulse Width Modulation).\n *\n * @method width\n * @param {Number} [width] Width between the pulses (0 to 1.0,\n * defaults to 0)\n */\n p5.Pulse.prototype.width = function(w) {\n if (typeof w === 'number') {\n if (w <= 1.0 && w >= 0.0) {\n this.w = w;\n // set delay time based on PWM width\n\n // var mW = map(this.w, 0, 1.0, 0, 1/this.f);\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n }\n\n this.dcGain.gain.value = 1.7*(0.5-this.w);\n } else {\n w.connect(this.dNode.delayTime);\n var sig = new p5.SignalAdd(-0.5);\n sig.setInput(w);\n sig = sig.mult(-1);\n sig = sig.mult(1.7);\n sig.connect(this.dcGain.gain);\n }\n };\n\n p5.Pulse.prototype.start = function(f, time) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.setValueAtTime(freq, now);\n this.oscillator.type = type;\n this.oscillator.connect(this.output);\n this.oscillator.start(t + now);\n\n // set up osc2\n this.osc2.oscillator = p5sound.audiocontext.createOscillator();\n this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);\n this.osc2.oscillator.type = type;\n this.osc2.oscillator.connect(this.osc2.output);\n this.osc2.start(t + now);\n this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency];\n\n // start dcOffset, too\n this.dcOffset = createDCOffset();\n this.dcOffset.connect(this.dcGain);\n this.dcOffset.start(t + now);\n\n // if LFO connections depend on these oscillators\n if (this.mods !== undefined && this.mods.frequency !== undefined) {\n this.mods.frequency.connect(this.freqNode[0]);\n this.mods.frequency.connect(this.freqNode[1]);\n }\n this.started = true;\n this.osc2.started = true;\n }\n };\n\n p5.Pulse.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n if (this.osc2.oscillator) {\n this.osc2.oscillator.stop(t + now);\n }\n this.dcOffset.stop(t + now);\n this.started = false;\n this.osc2.started = false;\n }\n };\n\n p5.Pulse.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number') {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var currentFreq = this.oscillator.frequency.value;\n this.oscillator.frequency.cancelScheduledValues(now);\n this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n this.osc2.oscillator.frequency.cancelScheduledValues(now);\n this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n\n if (this.freqMod) {\n this.freqMod.output.disconnect();\n this.freqMod = null;\n }\n\n } else if (val.output) {\n val.output.disconnect();\n val.output.connect(this.oscillator.frequency);\n val.output.connect(this.osc2.oscillator.frequency);\n this.freqMod = val;\n }\n };\n\n // inspiration: http://webaudiodemos.appspot.com/oscilloscope/\n function createDCOffset() {\n var ac = p5sound.audiocontext;\n var buffer=ac.createBuffer(1,2048,ac.sampleRate);\n var data = buffer.getChannelData(0);\n for (var i=0; i<2048; i++)\n data[i]=1.0;\n var bufferSource=ac.createBufferSource();\n bufferSource.buffer=buffer;\n bufferSource.loop=true;\n return bufferSource;\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * Noise is a type of oscillator that generates a buffer with random values.\n *\n * @class p5.Noise\n * @extends p5.Oscillator\n * @constructor\n * @param {String} type Type of noise can be 'white' (default),\n * 'brown' or 'pink'.\n */\n p5.Noise = function(type) {\n var assignType;\n p5.Oscillator.call(this);\n delete this.f;\n delete this.freq;\n delete this.oscillator;\n\n if (type === 'brown') {\n assignType = _brownNoise;\n } else if (type === 'pink') {\n assignType = _pinkNoise;\n } else {\n assignType = _whiteNoise;\n }\n this.buffer = assignType;\n };\n\n p5.Noise.prototype = Object.create(p5.Oscillator.prototype);\n\n // generate noise buffers\n var _whiteNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = whiteBuffer.getChannelData(0);\n for (var i = 0; i < bufferSize; i++) {\n noiseData[i] = Math.random() * 2 - 1;\n }\n whiteBuffer.type = 'white';\n return whiteBuffer;\n })();\n\n var _pinkNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = pinkBuffer.getChannelData(0);\n var b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.96900 * b2 + white * 0.1538520;\n b3 = 0.86650 * b3 + white * 0.3104856;\n b4 = 0.55000 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.0168980;\n noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n noiseData[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n pinkBuffer.type = 'pink';\n return pinkBuffer;\n })();\n\n var _brownNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = brownBuffer.getChannelData(0);\n var lastOut = 0.0;\n for (var i = 0; i< bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n noiseData[i] = (lastOut + 0.02*white) / 1.02;\n lastOut = noiseData[i];\n noiseData[i] *= 3.5;\n }\n brownBuffer.type = 'brown';\n return brownBuffer;\n })();\n\n /**\n * Set type of noise to 'white', 'pink' or 'brown'.\n * White is the default.\n *\n * @method setType\n * @param {String} [type] 'white', 'pink' or 'brown'\n */\n p5.Noise.prototype.setType = function(type) {\n switch(type) {\n case 'white':\n this.buffer = _whiteNoise;\n break;\n case 'pink':\n this.buffer = _pinkNoise;\n break;\n case 'brown':\n this.buffer = _brownNoise;\n break;\n default:\n this.buffer = _whiteNoise;\n }\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.start(now+.01);\n }\n };\n\n p5.Noise.prototype.getType = function() {\n return this.buffer.type;\n };\n\n p5.Noise.prototype.start = function() {\n if (this.started) {\n this.stop();\n }\n this.noise = p5sound.audiocontext.createBufferSource();\n this.noise.buffer = this.buffer;\n this.noise.loop = true;\n this.noise.connect(this.output);\n var now = p5sound.audiocontext.currentTime;\n this.noise.start(now);\n this.started = true;\n };\n\n p5.Noise.prototype.stop = function() {\n var now = p5sound.audiocontext.currentTime;\n if (this.noise) {\n this.noise.stop(now);\n this.started = false;\n }\n };\n\n p5.Noise.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.noise) {\n this.noise.disconnect();\n this.stop(now);\n }\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n }\n this.output = null;\n this.panner = null;\n this.buffer = null;\n this.noise = null;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // an array of input sources\n p5sound.inputSources = [];\n\n /**\n *

Get audio from an input, i.e. your computer's microphone.

\n *\n *

Turn the mic on/off with the start() and stop() methods. When the mic\n * is on, its volume can be measured with getLevel or by connecting an\n * FFT object.

\n *\n *

If you want to hear the AudioIn, use the .connect() method.\n * AudioIn does not connect to p5.sound output by default to prevent\n * feedback.

\n *\n *

Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.

\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * let mic;\n *\n * function setup(){\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(userStartAudio);\n * textAlign(CENTER);\n * mic = new p5.AudioIn();\n * mic.start();\n * }\n *\n * function draw(){\n * background(0);\n * fill(255);\n * text('tap to start', width/2, 20);\n *\n * micLevel = mic.getLevel();\n * let y = height - micLevel * height;\n * ellipse(width/2, y, 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables access.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method.
\n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers).
\n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers.
\n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel().
\n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0.
\n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n *
navigator.mediaDevices.enumerateDevices().
\n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.

\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * let eq, soundFile\n * let eqBandIndex = 0;\n * let eqBandNames = ['lows', 'mids', 'highs'];\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(toggleSound);\n *\n * eq = new p5.EQ(eqBandNames.length);\n * soundFile.disconnect();\n * eq.process(soundFile);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('filtering ', 50, 25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(eqBandNames[eqBandIndex], 50, 55);\n *\n * fill(255);\n * textSize(9);\n *\n * if (!soundFile.isPlaying()) {\n * text('tap to play', 50, 80);\n * } else {\n * text('tap to filter next band', 50, 80)\n * }\n * }\n *\n * function toggleSound() {\n * if (!soundFile.isPlaying()) {\n * soundFile.play();\n * } else {\n * eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n * }\n *\n * for (let i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * // filter the band we want to filter\n * eq.bands[eqBandIndex].gain(-40);\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner
\n// * p5.Listener3D - Constructs a Spatial Listener
\n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * default value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * osc = new p5.Oscillator('square');\n * osc.amp(0.5);\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime (in seconds), feedback, filter frequency\n * delay.process(osc, 0.12, .7, 2300);\n *\n * cnv.mousePressed(oscStart);\n * }\n *\n * function oscStart() {\n * osc.start();\n * }\n *\n * function mouseReleased() {\n * osc.stop();\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @for p5.Delay\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n * @for p5.Delay\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * }\n *\n * function draw() {\n * let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n * // 1 = all reverb, 0 = no reverb\n * reverb.drywet(dryWet);\n *\n * background(220);\n * text('tap to play', 10, 20);\n * text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n * }\n *\n * function playSound() {\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *

p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.

\n *\n *

Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.

\n *\n *

Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.

\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the convolver.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number).
\n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *

A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.

\n *\n *

Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.

\n *\n *

The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).

\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n * let mySound, myPhrase, myPart;\n * let pattern = [1,0,0,2,0,2,0,0];\n *\n * function preload() {\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * text('tap to play', width/2, height/2);\n * textAlign(CENTER, CENTER);\n *\n * myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n * myPart = new p5.Part();\n * myPart.addPhrase(myPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function onEachStep(time, playbackRate) {\n * mySound.rate(playbackRate);\n * mySound.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n * myPart.start();\n * }\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *

A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.

\n *\n *

See p5.Phrase for more about musical timing.

\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * let box, drum, myPart;\n * let boxPat = [1,0,0,2,0,2,0,0];\n * let drumPat = [0,1,1,0,2,0,1,0];\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * textAlign(CENTER, CENTER);\n * text('tap to play', width/2, height/2);\n *\n * let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n *\n * myPart.start();\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time (if a number) or beats (if a string, following Tone.Time convention) for each iteration of the loop. Defaults to 1 second.\n *\n * @example\n *
\n * let synth, soundLoop;\n * let notePattern = [60, 62, 64, 67, 69, 72];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * colorMode(HSB);\n * background(0, 0, 86);\n * text('tap to start/stop', 10, 20);\n *\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * let intervalInSeconds = 0.2;\n * soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n *\n * synth = new p5.MonoSynth();\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * if (soundLoop.isPlaying) {\n * soundLoop.stop();\n * } else {\n * // start the loop\n * soundLoop.start();\n * }\n * }\n *\n * function onSoundLoop(timeFromNow) {\n * let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n * let note = midiToFreq(notePattern[noteIndex]);\n * synth.play(note, 0.5, timeFromNow);\n * background(noteIndex * 360 / notePattern.length, 50, 100);\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n const p5sound = require('master');\n const { convertToWav, safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n const ac = p5sound.audiocontext;\n\n /**\n *

Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().

\n *

The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.

\n *\n * @class p5.SoundRecorder\n * @constructor\n * @example\n *
\n * let mic, recorder, soundFile;\n * let state = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * textAlign(CENTER, CENTER);\n *\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('tap to record', width/2, height/2);\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', width/2, height/2);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Done! Tap to play and download', width/2, height/2, width - 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n const workletBufferSize = safeBufferSize(1024);\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: {\n numInputChannels: this._inputChannels,\n bufferSize: workletBufferSize\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *

PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *

\n *

\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *

\n *

\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *

\n *\n *

threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.

\n *\n *

\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *

\n *\n *

\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *

\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n *\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 10;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n *\n * // p5.PeakDetect requires a p5.FFT\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n * }\n *\n * function draw() {\n * background(0);\n * text('click to play/pause', width/2, height/2);\n *\n * // peakDetect accepts an fft post-analysis\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * if ( peakDetect.isDetected ) {\n * ellipseWidth = 50;\n * } else {\n * ellipseWidth *= 0.95;\n * }\n *\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // toggle play/stop when canvas is clicked\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * }\n * }\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * let sound1,sound2;\n * let sound1Gain, sound2Gain, masterGain;\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * // create a 'master' gain to which we will connect both soundfiles\n * masterGain = new p5.Gain();\n * masterGain.connect();\n * sound1.disconnect(); // diconnect from p5 output\n * sound1Gain = new p5.Gain(); // setup a gain node\n * sound1Gain.setInput(sound1); // connect the first sound to its input\n * sound1Gain.connect(masterGain); // connect its output to the 'master'\n * sound2.disconnect();\n * sound2Gain = new p5.Gain();\n * sound2Gain.setInput(sound2);\n * sound2Gain.connect(masterGain);\n * }\n * function startSound() {\n * sound1.loop();\n * sound2.loop();\n * loop();\n * }\n * function mouseReleased() {\n * sound1.stop();\n * sound2.stop();\n * }\n * function draw(){\n * background(220);\n * textAlign(CENTER);\n * textSize(11);\n * fill(0);\n * if (!sound1.isPlaying()) {\n * text('tap and drag to play', width/2, height/2);\n * return;\n * }\n * // map the horizontal position of the mouse to values useable for volume * control of sound1\n * var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n * var sound2Volume = 1-sound1Volume;\n * sound1Gain.amp(sound1Volume);\n * sound2Gain.amp(sound2Volume);\n * // map the vertical position of the mouse to values useable for 'master * volume control'\n * var masterVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n * masterGain.amp(masterVolume);\n * text('master', width/2, height - masterVolume * height * 0.9)\n * fill(255, 0, 255);\n * textAlign(LEFT);\n * text('sound1', 5, height - sound1Volume * height * 0.9);\n * textAlign(RIGHT);\n * text('sound2', width - 5, height - sound2Volume * height * 0.9);\n * }\n *
\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./effect.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","prototype","set","params","value","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","i","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","get","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","Object","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","defineProperty","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","call","isBoolean","noOp","_readOnly","property","writable","enumerable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasOwnProperty","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","console","audiocontext","Master","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5sound","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","startTime","endTime","drywet","fade","u","index","undefined","processorNames","freqToMidi","f","mathlog2","m","round","midiToFreq","noteToFreq","note","wholeNotes","A","B","C","D","E","F","G","toUpperCase","octave","slice","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","supported","p","_mathChain","o","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","rightChannel","getChannelData","numberOfChannels","interleaved","interleave","buffer","ArrayBuffer","view","DataView","writeUTFBytes","setUint32","setUint16","lng","volume","setInt16","result","inputIndex","offset","string","setUint8","charCodeAt","safeBufferSize","idealBufferSize","bufferSize","tempAudioWorkletNode","AudioWorkletNode","soundFileProcessor","ScriptProcessorNode","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","module","exports","recorderProcessor","amplitudeProcessor","toneConnect","outNum","inNum","nativeConnect","e","Error","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","bind","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","warn","CustomError","name","errorTrace","failedPath","err","tempStack","splitStack","originalStack","stack","filter","ln","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","add","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","t","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","create","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","object","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","n","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","s","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","DEFAULT_SUSTAIN","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","d","r","timeFromNow","voice","_note","_velocity","acTime","currentVoice","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","parameters","fill","processor","realm","exec","inputBuffer","outputBuffer","$$processors","$$context","self","createScriptProcessor","outputChannelCount","Map","properties","c","l","defaultValue","MessageChannel","port2","Processor","port","port1","onaudioprocess","$$audioWorklet","AudioWorklet","addModule","fetch","then","ok","status","text","AudioWorkletProcessor","registerProcessor","parameterDescriptors","document","createElement","style","cssText","appendChild","contentWindow","createTextNode","body","$hook","documentElement","transpile","String","fixSetTarget","setTargetValueAtTime","createDelayNode","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","when","noteGrainOn","noteOn","internal_start","noteOff","internal_stop","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","isSupported","canPlayType","isOGGSupported","isMP3Supported","isWAVSupported","isAACSupported","isAIFSupported","g","Function","root","factory","amd","TapListener","element","_dragged","_element","_bindedMove","_moved","_bindedEnd","_ended","isStarted","source","resume","startContext","removeEventListener","promise","Promise","success","checkLoop","requestAnimationFrame","onStarted","tapListeners","bindTapListener","NodeList","querySelectorAll","jquery","toArray","tap","moduleSources","initializedAudioWorklets","loadAudioWorkletModules","all","moduleSrc","objectURL","audioWorklet","preload","_incrementPreload","onWorkletModulesLoad","_decrementPreload","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","mode","startMillis","load","_whileLoading","_clearOnEnd","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","decodeAudioData","response","buff","msg","error","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverse","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","chan","currentPos","curVol","onended","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","channel","_createCounterBuffer","audioBuf","arrayBuffer","cNode","workletBufferSize","processorOptions","onmessage","data","_onTimeUpdate","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","initialThreshold","minThreshold","minPeaks","offlineContext","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","intervalCounts","countIntervalsBetweenNearbyPeaks","groups","groupNeighborsByTempo","topTempos","sort","intA","intB","count","tempo","bpmVariance","tempoPeaks","getPeaksAtTopTempo","Peak","sampleIndex","amplitude","tempos","intervals","peaksObj","peak","peaksArray","startPeak","endPeak","startPos","endPos","foundInterval","some","intervalCount","tempoCounts","theoreticalTempo","mapTempo","foundTempo","tempoCount","peaksAtTopTempo","key","intervalBPM","peakTime","dif","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevUpdateTime","save","fileName","saveSound","getBlob","dataView","thisBufferSourceNode","target","soundFile","_","Amplitude","smoothing","parameterData","normalize","volNorm","stereoVol","stereoVolNorm","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","toReturn","freq1","freq2","x","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","spec_centroid_freq","linAverages","_N","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","specIndexFrequency","hi","getOctaveBands","_fCtr0","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","fft","_input","midi","midiToFrequency","pitch","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","Pulse","w","dcOffset","createDCOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","bufferSource","_whiteNoiseBuffer","whiteBuffer","noiseData","random","_pinkNoiseBuffer","pinkBuffer","b0","b1","b2","b3","b4","b5","b6","white","_brownNoiseBuffer","brownBuffer","lastOut","assignType","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","parseArgumentList","parseFunctionCall","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","_path","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","currentPart","thisScore","nextPart","resetPart","playNextPart","resetParts","scoreStep","aScore","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","numSamples","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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","file":"p5.sound.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *

\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\ndefine(['audiocontext'], function (audiocontext) {\n // Master contains the master sound output.\n var Master = function () {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function () {\n return p5sound.output.gain.value;\n };\n\n /**\n *

Scale the output of all sound in this sketch

\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *

How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.

\n *\n *

If no value is provided, returns a Web Audio API Gain Node

\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function (vol, rampTime = 0, tFromNow = 0) {\n if (typeof vol === 'number') {\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(\n vol,\n now + tFromNow + rampTime\n );\n } else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n // a silent connection to the DesinationNode\n // which will ensure that anything connected to it\n // will not be garbage collected\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/SignalBase\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Wraps the native Web Audio API \n\t * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {function|Array|Number} mapping The function used to define the values. \n\t * The mapping function should take two arguments: \n\t * the first is the value at the current position \n\t * and the second is the array position. \n\t * If the argument is an array, that array will be\n\t * set as the wave shaping function. The input\n\t * signal is an AudioRange [-1, 1] value and the output\n\t * signal can take on any numerical values. \n\t * \n\t * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer.\n\t * @example\n\t * var timesTwo = new Tone.WaveShaper(function(val){\n\t * \treturn val * 2;\n\t * }, 2048);\n\t * @example\n\t * //a waveshaper can also be constructed with an array of values\n\t * var invert = new Tone.WaveShaper([1, -1]);\n\t */\n\tTone.WaveShaper = function(mapping, bufferLen){\n\n\t\t/**\n\t\t * the waveshaper\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._shaper = this.input = this.output = this.context.createWaveShaper();\n\n\t\t/**\n\t\t * the waveshapers curve\n\t\t * @type {Float32Array}\n\t\t * @private\n\t\t */\n\t\tthis._curve = null;\n\n\t\tif (Array.isArray(mapping)){\n\t\t\tthis.curve = mapping;\n\t\t} else if (isFinite(mapping) || this.isUndef(mapping)){\n\t\t\tthis._curve = new Float32Array(this.defaultArg(mapping, 1024));\n\t\t} else if (this.isFunction(mapping)){\n\t\t\tthis._curve = new Float32Array(this.defaultArg(bufferLen, 1024));\n\t\t\tthis.setMap(mapping);\n\t\t} \n\t};\n\n\tTone.extend(Tone.WaveShaper, Tone.SignalBase);\n\n\t/**\n\t * Uses a mapping function to set the value of the curve. \n\t * @param {function} mapping The function used to define the values. \n\t * The mapping function take two arguments: \n\t * the first is the value at the current position \n\t * which goes from -1 to 1 over the number of elements\n\t * in the curve array. The second argument is the array position. \n\t * @returns {Tone.WaveShaper} this\n\t * @example\n\t * //map the input signal from [-1, 1] to [0, 10]\n\t * shaper.setMap(function(val, index){\n\t * \treturn (val + 1) * 5;\n\t * })\n\t */\n\tTone.WaveShaper.prototype.setMap = function(mapping){\n\t\tfor (var i = 0, len = this._curve.length; i < len; i++){\n\t\t\tvar normalized = (i / (len - 1)) * 2 - 1;\n\t\t\tthis._curve[i] = mapping(normalized, i);\n\t\t}\n\t\tthis._shaper.curve = this._curve;\n\t\treturn this;\n\t};\n\n\t/**\n\t * The array to set as the waveshaper curve. For linear curves\n\t * array length does not make much difference, but for complex curves\n\t * longer arrays will provide smoother interpolation. \n\t * @memberOf Tone.WaveShaper#\n\t * @type {Array}\n\t * @name curve\n\t */\n\tObject.defineProperty(Tone.WaveShaper.prototype, \"curve\", {\n\t\tget : function(){\n\t\t\treturn this._shaper.curve;\n\t\t},\n\t\tset : function(mapping){\n\t\t\tthis._curve = new Float32Array(mapping);\n\t\t\tthis._shaper.curve = this._curve;\n\t\t}\n\t});\n\n\t/**\n\t * Specifies what type of oversampling (if any) should be used when \n\t * applying the shaping curve. Can either be \"none\", \"2x\" or \"4x\". \n\t * @memberOf Tone.WaveShaper#\n\t * @type {string}\n\t * @name oversample\n\t */\n\tObject.defineProperty(Tone.WaveShaper.prototype, \"oversample\", {\n\t\tget : function(){\n\t\t\treturn this._shaper.oversample;\n\t\t},\n\t\tset : function(oversampling){\n\t\t\tif ([\"none\", \"2x\", \"4x\"].indexOf(oversampling) !== -1){\n\t\t\t\tthis._shaper.oversample = oversampling;\n\t\t\t} else {\n\t\t\t\tthrow new RangeError(\"Tone.WaveShaper: oversampling must be either 'none', '2x', or '4x'\");\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.WaveShaper} this\n\t */\n\tTone.WaveShaper.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.disconnect();\n\t\tthis._shaper = null;\n\t\tthis._curve = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.WaveShaper;\n});","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5.
\n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function () {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n const now = p5sound.audiocontext.currentTime;\n const startTime = now + tFromNow;\n const endTime = startTime + rampTime + 0.001;\n const currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, startTime + 0.001);\n this.output.gain.linearRampToValueAtTime(vol, endTime);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function () {\n if (arguments.length > 0) {\n this.connect(arguments[0]);\n for (var i = 1; i < arguments.length; i += 1) {\n arguments[i - 1].connect(arguments[i]);\n }\n }\n return this;\n };\n\n /**\n * Adjust the dry/wet value.\n *\n * @method drywet\n * @for p5.Effect\n * @param {Number} [fade] The desired drywet value (0 - 1.0)\n */\n p5.Effect.prototype.drywet = function (fade) {\n if (typeof fade !== 'undefined') {\n this._drywet.fade.value = fade;\n }\n return this._drywet.fade.value;\n };\n\n /**\n * Send output to a p5.js-sound, Web Audio Node, or use signal to\n * control an AudioParam\n *\n * @method connect\n * @for p5.Effect\n * @param {Object} unit\n */\n p5.Effect.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n * @method disconnect\n * @for p5.Effect\n */\n p5.Effect.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n p5.Effect.prototype.dispose = function () {\n // remove refernce form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n if (this._drywet) {\n this._drywet.disconnect();\n delete this._drywet;\n }\n\n if (this.wet) {\n this.wet.disconnect();\n delete this.wet;\n }\n\n this.ac = undefined;\n };\n\n return p5.Effect;\n});\n","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n /**\n * @for p5\n */\n\n /**\n * Returns a number representing the sample rate, in samples per second,\n * of all sound objects in this audio context. It is determined by the\n * sampling rate of your operating system's sound card, and it is not\n * currently possile to change.\n * It is often 44100, or twice the range of human hearing.\n *\n * @method sampleRate\n * @return {Number} samplerate samples per second\n */\n p5.prototype.sampleRate = function () {\n return p5sound.audiocontext.sampleRate;\n };\n\n /**\n * Returns the closest MIDI note value for\n * a given frequency.\n *\n * @method freqToMidi\n * @param {Number} frequency A freqeuncy, for example, the \"A\"\n * above Middle C is 440Hz\n * @return {Number} MIDI note value\n */\n p5.prototype.freqToMidi = function (f) {\n var mathlog2 = Math.log(f / 440) / Math.log(2);\n var m = Math.round(12 * mathlog2) + 69;\n return m;\n };\n\n /**\n * Returns the frequency value of a MIDI note value.\n * General MIDI treats notes as integers where middle C\n * is 60, C# is 61, D is 62 etc. Useful for generating\n * musical frequencies with oscillators.\n *\n * @method midiToFreq\n * @param {Number} midiNote The number of a MIDI note\n * @return {Number} Frequency value of the given MIDI note\n * @example\n *
\n * let midiNotes = [60, 64, 67, 72];\n * let noteIndex = 0;\n * let midiVal, freq;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * osc = new p5.TriOsc();\n * env = new p5.Envelope();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 10, 20);\n * if (midiVal) {\n * text('MIDI: ' + midiVal, 10, 40);\n * text('Freq: ' + freq, 10, 60);\n * }\n * }\n *\n * function startSound() {\n * // see also: userStartAudio();\n * osc.start();\n *\n * midiVal = midiNotes[noteIndex % midiNotes.length];\n * freq = midiToFreq(midiVal);\n * osc.freq(freq);\n * env.ramp(osc, 0, 1.0, 0);\n *\n * noteIndex++;\n * }\n *
\n */\n var midiToFreq = (p5.prototype.midiToFreq = function (m) {\n return 440 * Math.pow(2, (m - 69) / 12.0);\n });\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function (note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = { A: 21, B: 23, C: 24, D: 26, E: 28, F: 29, G: 31 };\n var value = wholeNotes[note[0].toUpperCase()];\n var octave = ~~note.slice(-1);\n value += 12 * (octave - 1);\n\n switch (note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('sound loaded! tap to play', 10, 20, width - 20);\n * cnv.mousePressed(function() {\n * mySound.play();\n * });\n * }\n *
\n */\n p5.prototype.soundFormats = function () {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function () {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function (paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (!p5.prototype.isFileSupported(extTest)) {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (let i = 0; i < p5sound.extensions.length; i++) {\n const extension = p5sound.extensions[i];\n const supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n pathCore = '';\n if (pathSplit.length === 2) {\n pathCore += pathSplit[0];\n }\n for (let i = 1; i <= pathSplit.length - 2; i++) {\n var p = pathSplit[i];\n pathCore += '.' + p;\n }\n path = pathCore += '.';\n path = path += extension;\n break;\n }\n }\n }\n }\n // if no extension is provided...\n else {\n for (let i = 0; i < p5sound.extensions.length; i++) {\n const extension = p5sound.extensions[i];\n const supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n path = path + '.' + extension;\n break;\n }\n }\n }\n } // end 'if string'\n\n // path can either be a single string, or an array\n else if (typeof paths === 'object') {\n for (var i = 0; i < paths.length; i++) {\n var extension = paths[i].split('.').pop();\n var supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n // console.log('.'+extension + ' is ' + supported +\n // ' supported by your browser.');\n path = paths[i];\n break;\n }\n }\n }\n return path;\n };\n\n /**\n * Used by Osc and Envelope to chain signal math\n */\n p5.prototype._mathChain = function (o, math, thisChain, nextChain, type) {\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n o.mathOps[i].dispose();\n thisChain = i;\n if (thisChain < o.mathOps.length - 1) {\n nextChain = o.mathOps[i + 1];\n }\n }\n }\n o.mathOps[thisChain - 1].disconnect();\n o.mathOps[thisChain - 1].connect(math);\n math.connect(nextChain);\n o.mathOps[thisChain] = math;\n return o;\n };\n\n // helper methods to convert audio file as .wav format,\n // will use as saving .wav file and saving blob object\n // Thank you to Matt Diamond's RecorderJS (MIT License)\n // https://github.com/mattdiamond/Recorderjs\n function convertToWav(audioBuffer) {\n var leftChannel, rightChannel;\n leftChannel = audioBuffer.getChannelData(0);\n\n // handle mono files\n if (audioBuffer.numberOfChannels > 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7fff * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length; ) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n function safeBufferSize(idealBufferSize) {\n let bufferSize = idealBufferSize;\n\n // if the AudioWorkletNode is actually a ScriptProcessorNode created via polyfill,\n // make sure that our chosen buffer size isn't smaller than the buffer size automatically\n // selected by the polyfill\n // reference: https://github.com/GoogleChromeLabs/audioworklet-polyfill/issues/13#issuecomment-425014930\n let tempAudioWorkletNode = new AudioWorkletNode(\n p5sound.audiocontext,\n processorNames.soundFileProcessor\n );\n if (tempAudioWorkletNode instanceof ScriptProcessorNode) {\n bufferSize = tempAudioWorkletNode.bufferSize;\n }\n tempAudioWorkletNode.disconnect();\n tempAudioWorkletNode = null;\n\n return bufferSize;\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq,\n safeBufferSize: safeBufferSize,\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
    \n\t\t *
  • Numbers, which will be taken literally as the time (in seconds).
  • \n\t\t *
  • Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
  • \n\t\t *
  • TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
  • \n\t\t *
  • Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
  • \n\t\t *
  • Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
  • \n\t\t *
  • Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
  • \n\t\t *
  • No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
  • \n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
    \n\t\t * \t
  • \"4n\" = quarter note
  • \n\t\t * \t
  • \"2m\" = two measures
  • \n\t\t * \t
  • \"8t\" = eighth-note triplet
  • \n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor',\n};\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function (name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n splitStack = tempStack.split('\\n').filter(function (ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *

A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:

\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff.
\n * p5.HighPass:\n * The opposite of a lowpass filter.
\n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range.
\n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * let fft, noise, filter;\n *\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(makeNoise);\n * fill(255, 0, 255);\n *\n * filter = new p5.BandPass();\n * noise = new p5.Noise();\n * noise.disconnect();\n * noise.connect(filter);\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(220);\n *\n * // set the BandPass frequency based on mouseX\n * let freq = map(mouseX, 0, width, 20, 10000);\n * freq = constrain(freq, 0, 22050);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * let spectrum = fft.analyze();\n * noStroke();\n * for (let i = 0; i < spectrum.length; i++) {\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n * if (!noise.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n * }\n * }\n *\n * function makeNoise() {\n * // see also: `userStartAudio()`\n * noise.start();\n * noise.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * noise.amp(0, 0.2);\n * }\n *\n *
\n */\n p5.Filter = function (type) {\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function (src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function (freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function (freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.biquad.frequency.exponentialRampToValueAtTime(\n freq,\n this.ac.currentTime + 0.02 + t\n );\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function (res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(\n res,\n this.ac.currentTime + 0.02 + t\n );\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function (gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(\n gain,\n this.ac.currentTime + 0.02 + t\n );\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function () {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function (t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function () {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function () {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function () {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function () {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (\n StartAudioContext,\n Context,\n Tone\n) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *

Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .

\n *\n *

Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.

\n *\n * @for p5\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
\n */\n p5.prototype.getAudioContext = function () {\n return audiocontext;\n };\n\n /**\n *

It is not only a good practice to give users control over starting\n * audio. This policy is enforced by many web browsers, including iOS and\n * Google Chrome, which create the Web Audio API's\n * Audio Context\n * in a suspended state.

\n *\n *

In these browser-specific policies, sound will not play until a user\n * interaction event (i.e. mousePressed()) explicitly resumes\n * the AudioContext, or starts an audio node. This can be accomplished by\n * calling start() on a p5.Oscillator,\n * play() on a p5.SoundFile, or simply\n * userStartAudio().

\n *\n *

userStartAudio() starts the AudioContext on a user\n * gesture. The default behavior will enable audio on any\n * mouseUp or touchEnd event. It can also be placed in a specific\n * interaction function, such as mousePressed() as in the\n * example below. This method utilizes\n * StartAudioContext\n * , a library by Yotam Mann (MIT Licence, 2016).

\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext\n * has started\n * @return {Promise} Returns a Promise that resolves when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * // mimics the autoplay policy\n * getAudioContext().suspend();\n *\n * let mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has resumed\n * mySynth.play('A6');\n * }\n * function draw() {\n * background(220);\n * textAlign(CENTER, CENTER);\n * text(getAudioContext().state, width/2, height/2);\n * }\n * function mousePressed() {\n * userStartAudio();\n * }\n *
\n */\n p5.prototype.userStartAudio = function (elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element) {\n elt = elements.map(function (e) {\n return e.elt;\n });\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).

\n *\n *

Set the type of oscillation with setType(), or by instantiating a\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\n *

\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * let osc, playing, freq, amp;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator('sine');\n * }\n *\n * function draw() {\n * background(220)\n * freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n * amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n *\n * text('tap to play', 20, 20);\n * text('freq: ' + freq, 20, 40);\n * text('amp: ' + amp, 20, 60);\n *\n * if (playing) {\n * // smooth the transitions by 0.1 seconds\n * osc.freq(freq, 0.1);\n * osc.amp(amp, 0.1);\n * }\n * }\n *\n * function playOscillator() {\n * // starting an oscillator on a user gesture will enable audio\n * // in browsers that have a strict autoplay policy.\n * // See also: userStartAudio();\n * osc.start();\n * playing = true;\n * }\n *\n * function mouseReleased() {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * }\n *
\n */\n p5.Oscillator = function (freq, type) {\n if (typeof freq === 'string') {\n let f = type;\n type = freq;\n freq = f;\n }\n if (typeof type === 'number') {\n let f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(\n this.f,\n p5sound.audiocontext.currentTime\n );\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator.\n *\n * Starting an oscillator on a user gesture will enable audio in browsers\n * that have a strict autoplay policy, including Chrome and most mobile\n * devices. See also: `userStartAudio()`.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function (time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function (time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n if (typeof vol === 'number') {\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n } else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function () {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator(300);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playOscillator() {\n * osc.start();\n * osc.amp(0.5);\n * // start at 700Hz\n * osc.freq(700);\n * // ramp to 60Hz over 0.7 seconds\n * osc.freq(60, 0.7);\n * osc.amp(0, 0.1, 0.7);\n * }\n *
\n */\n p5.Oscillator.prototype.freq = function (val, rampTime = 0, tFromNow = 0) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0) {\n this.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push(val);\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function () {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function (type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function () {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function (unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n } else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n } else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function (pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function () {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function (p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1 / this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function (o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i + 1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i - 1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function (num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function (num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n } else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds.\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n susTime\n ) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (\n note,\n velocity,\n secondsFromNow = 0\n ) {\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow = 0) {\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack, decay, sustain, release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n attack: {\n get: function () {\n return this.env.aTime;\n },\n set: function (attack) {\n this.env.setADSR(\n attack,\n this.env.dTime,\n this.env.sPercent,\n this.env.rTime\n );\n },\n },\n decay: {\n get: function () {\n return this.env.dTime;\n },\n set: function (decay) {\n this.env.setADSR(\n this.env.aTime,\n decay,\n this.env.sPercent,\n this.env.rTime\n );\n },\n },\n sustain: {\n get: function () {\n return this.env.sPercent;\n },\n set: function (sustain) {\n this.env.setADSR(\n this.env.aTime,\n this.env.dTime,\n sustain,\n this.env.rTime\n );\n },\n },\n release: {\n get: function () {\n return this.env.rTime;\n },\n set: function (release) {\n this.env.setADSR(\n this.env.aTime,\n this.env.dTime,\n this.env.sPercent,\n release\n );\n },\n },\n });\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function (vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function () {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n});\n","'use strict';\ndefine(function () {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n this.ac = p5sound.audiocontext;\n this.output = this.ac.createGain();\n this.connect();\n p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n sustime\n ) {};\n\n p5.AudioVoice.prototype.triggerAttack = function (\n note,\n velocity,\n secondsFromNow\n ) {};\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {};\n\n p5.AudioVoice.prototype.amp = function (vol, rampTime) {};\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function () {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function () {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n **/\n p5.PolySynth = function (audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function () {\n for (var i = 0; i < this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n susTime = 1\n ) {\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (\n note,\n a,\n d,\n s,\n r,\n timeFromNow = 0\n ) {\n var now = p5sound.audiocontext.currentTime;\n var t = now + timeFromNow;\n this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r);\n };\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function (a, d, s, r) {\n this.audiovoices.forEach(function (voice) {\n voice.setADSR(a, d, s, r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (\n _note,\n _velocity,\n secondsFromNow = 0\n ) {\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(\n this.audiovoices[this._oldest].oscillator.freq().value\n );\n this.noteRelease(oldestNote);\n this._oldest = (this._oldest + 1) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal =\n this._voicesInUse._searchBefore(acTime) === null\n ? 0\n : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = (1 / this._voicesInUse.getValueAtTime(acTime)) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n\n // use secondsFromNow because this method will add AudioContext currentTime\n this.audiovoices[currentVoice].triggerAttack(\n note,\n velocity,\n secondsFromNow\n );\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function (time, value) {\n if (this._voicesInUse._searchAfter(time) === null) {\n return;\n } else {\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function (voice) {\n voice.triggerRelease(tFromNow);\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(\n ~~this._voicesInUse.getValueAtTime(t).value,\n 1\n );\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[this.notes[note].getValueAtTime(t)].triggerRelease(\n tFromNow\n );\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest =\n this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function () {\n this.audiovoices.forEach(function (voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this._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; 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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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; 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);\"","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if (typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function (val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function () {};\n\n p5.Panner.prototype.connect = function (obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function () {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function (input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n } else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function (val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos((v * Math.PI) / 2);\n var leftVal = Math.sin((v * Math.PI) / 2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function (numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof this.splitter === 'undefined') {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function (obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const CustomError = require('errorHandler');\n const p5sound = require('master');\n const ac = p5sound.audiocontext;\n const { midiToFreq, convertToWav, safeBufferSize } = require('helpers');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *

SoundFile object with a path to a file.

\n *\n *

The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.

\n *\n *

To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.

\n *\n *

Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.

\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile = function (paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n } else if (typeof paths === 'object') {\n if (\n !(window.File && window.FileReader && window.FileList && window.Blob)\n ) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function () {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function () {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.prototype.loadSound = function (path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n window.alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n\n var self = this;\n var s = new p5.SoundFile(\n path,\n function () {\n if (typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n },\n onerror,\n whileLoading\n );\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function (callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener(\n 'progress',\n function (evt) {\n self._updateProgress(evt);\n },\n false\n );\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function () {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(\n request.response,\n // success decoding buffer:\n function (buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function () {\n if (!self.panner) return;\n var err = new CustomError(\n 'decodeAudioData',\n errorTrace,\n self.url\n );\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg =\n 'Unable to load ' +\n self.url +\n '. The request status was: ' +\n request.status +\n ' (' +\n request.statusText +\n ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function () {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg =\n 'There was no response from the server at ' +\n self.url +\n '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n };\n\n request.send();\n } else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function () {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function (buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function (e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function (evt) {\n if (evt.lengthComputable) {\n var percentComplete = (evt.loaded / evt.total) * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function () {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function (\n startTime,\n rate,\n amp,\n _cueStart,\n duration\n ) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >= 0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else {\n throw 'start time out of range';\n }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration =\n duration <= this.buffer.duration - cueStart\n ? duration\n : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n };\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * let mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * noFill();\n * rect(0, height/2, width - 1, height/2 - 1);\n * rect(0, 0, width - 1, height/2);\n * textAlign(CENTER, CENTER);\n * fill(20);\n * text('restart', width/2, 1 * height/4);\n * text('sustain', width/2, 3 * height/4);\n * }\n * function canvasPressed() {\n * if (mouseX < height/2) {\n * mySound.playMode('restart');\n * } else {\n * mySound.playMode('sustain');\n * }\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function (str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n * let soundFile;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.pause = function (startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n * @example\n *
\n * let soundFile;\n * let loopStart = 0.5;\n * let loopDuration = 0.2;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.loop = function (\n startTime,\n rate,\n amp,\n loopStart,\n duration\n ) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function (bool) {\n if (bool === true) {\n this._looping = true;\n } else if (bool === false) {\n this._looping = false;\n } else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function () {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function () {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function () {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function (timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n } else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function (_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch (e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function (vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n } else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function () {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n * let ballX = 0;\n * let soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * ballX = constrain(mouseX, 0, width);\n * ellipse(ballX, height/2, 20, 20);\n * }\n *\n * function canvasPressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * let panning = map(ballX, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function (pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function () {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * let mySound;\n *\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * }\n * function canvasPressed() {\n * mySound.loop();\n * }\n * function mouseReleased() {\n * mySound.pause();\n * }\n * function draw() {\n * background(220);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * let playbackRate = map(mouseY, 0.1, height, 2, 0);\n * playbackRate = constrain(playbackRate, 0.01, 4);\n * mySound.rate(playbackRate);\n *\n * line(0, mouseY, width, mouseY);\n * text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function (playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n } else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n } else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(\n Math.abs(playbackRate),\n now\n );\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(\n Math.abs(playbackRate),\n now\n );\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function (num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function () {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function () {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function () {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of a soundfile that is currently playing to a\n * new position and a new duration, in seconds.\n * If none are given, will reset the file to play entire duration\n * from start to finish. To set the position of a soundfile that is\n * not currently playing, use the `play` or `loop` methods.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function (cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n }\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function () {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function () {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function () {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function (length) {\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width * 5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i * sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j += sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n } else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * let drum;\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function canvasPressed() {\n * drum.stop();\n * drum.reverseBuffer();\n * drum.play();\n * }\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function () {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (this.isPlaying() && currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function (callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function () {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function () {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch (e) {\n console.warn('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if (this.isPlaying()) {\n try {\n this._counterNode.stop(now);\n } catch (e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function (unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n } else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function () {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function () {\n console.warn(\n 'p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead'\n );\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function (p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function (buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData(channelNum);\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function (buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer(1, buffer.length, ac.sampleRate);\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function () {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n const workletBufferSize = safeBufferSize(256);\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(\n ac,\n processorNames.soundFileProcessor,\n {\n processorOptions: { bufferSize: workletBufferSize },\n }\n );\n self._workletNode.port.onmessage = (event) => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer(self.buffer);\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function () {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function (\n callback,\n _initThreshold,\n _minThreshold,\n _minPeaks\n ) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function (e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (\n Object.keys(allPeaks).length < minPeaks &&\n threshold >= minThreshold\n );\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(\n intervalCounts,\n filteredBuffer.sampleRate\n );\n\n // sort top intervals\n var topTempos = groups\n .sort(function (intA, intB) {\n return intB.count - intA.count;\n })\n .splice(0, 5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(\n allPeaks,\n topTempos[0].tempo,\n filteredBuffer.sampleRate,\n bpmVariance\n );\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function (amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function (intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function (intervalCount) {\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs(\n 60 / (intervalCount.interval / sampleRate)\n );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function (tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return (tempoCount.count += intervalCount.count);\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count,\n });\n }\n } catch (e) {\n throw e;\n }\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(\n Math.abs(60 / (peak.intervals[j] / sampleRate))\n );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if (Math.abs(intervalBPM - tempo) < bpmVariance) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex / sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function (peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90)\n theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function (callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 10, 20);\n *\n * // schedule calls to changeText\n * mySound.addCue(0, changeText, \"hello\" );\n * mySound.addCue(0.5, changeText, \"hello,\" );\n * mySound.addCue(1, changeText, \"hello, p5!\");\n * mySound.addCue(1.5, changeText, \"hello, p5!!\");\n * mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n * }\n *\n * function changeText(val) {\n * background(220);\n * text(val, 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile.prototype.addCue = function (time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function (id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function () {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function (position) {\n var playbackTime = position / this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (\n ~~this._prevUpdateTime <= callbackTime &&\n callbackTime <= playbackTime\n ) {\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n }\n\n this._prevUpdateTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to download', 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.save('my cool filename');\n * }\n *
\n */\n p5.SoundFile.prototype.save = function (fileName) {\n p5.prototype.saveSound(this, fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * let soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * let httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * let blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function () {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n // delete bufferSourceNode(s) in soundFile.bufferSourceNodes\n // iterate in reverse order because the index changes by splice\n soundFile.bufferSourceNodes\n .map((_, i) => i)\n .reverse()\n .forEach(function (i) {\n const n = soundFile.bufferSourceNodes[i];\n\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i, 1);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const p5sound = require('master');\n const { safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * let sound, amplitude;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *\n *
\n */\n p5.Amplitude = function (smoothing) {\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = safeBufferSize(2048);\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(\n this.audiocontext,\n processorNames.amplitudeProcessor,\n {\n outputChannelCount: [1],\n\n parameterData: { smoothing: smoothing || 0 },\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0,\n numInputChannels: 2,\n bufferSize: this.bufferSize,\n },\n }\n );\n\n this._workletNode.port.onmessage = function (event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n *\n * amplitude = new p5.Amplitude();\n * amplitude.setInput(sound2);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound1.isPlaying() && sound2.isPlaying()) {\n * sound1.stop();\n * sound2.stop();\n * } else {\n * sound1.play();\n * sound2.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function (source, smoothing) {\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log(\n 'Amplitude input source is not ready! Connecting to master output instead'\n );\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function (unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220, 150);\n * textAlign(CENTER);\n * text('tap to play', width/2, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound.isPlaying()) {\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function (channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n } else if (this.normalize) {\n return this.volNorm;\n } else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function (bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n } else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({\n name: 'toggleNormalize',\n normalize: this.normalize,\n });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function (s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n *

FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.

\n *\n *

Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses:
• FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time.
\n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.

\n *\n *

FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.

\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(220);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * let waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(20);\n * for (let i = 0; i < waveform.length; i++){\n * let x = map(i, 0, waveform.length, 0, width);\n * let y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('tap to play', 20, 20);\n * }\n *\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function (smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function () {\n return this.analyser.fftSize / 2;\n },\n set: function (b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true,\n },\n smoothing: {\n get: function () {\n return this.analyser.smoothingTimeConstant;\n },\n set: function (s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true,\n },\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function (source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function () {\n var bins, mode;\n var normalArray = new Array();\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * let osc, fft;\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(startSound);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(220);\n *\n * let freq = map(mouseX, 0, windowWidth, 20, 10000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * if (!osc.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text(round(freq)+'Hz', 10, 20);\n * }\n * }\n *\n * function startSound() {\n * osc.start();\n * osc.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * osc.amp(0, 0.2);\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function () {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n\n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.

\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function (frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round((frequency1 / nyquist) * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(\n (frequency1 / nyquist) * this.freqDomain.length\n );\n var highIndex = Math.round(\n (frequency2 / nyquist) * this.freqDomain.length\n );\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function (freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.

\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n * function setup(){\n * cnv = createCanvas(100,100);\n * cnv.mousePressed(userStartAudio);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *function draw() {\n * if (getAudioContext().state !== 'running') {\n * background(220);\n * text('tap here and enable mic to begin', 10, 20, width - 20);\n * return;\n * }\n * let centroidplot = 0.0;\n * let spectralCentroid = 0;\n *\n * background(0);\n * stroke(0,255,0);\n * let spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (let i = 0; i < spectrum.length; i++){\n * let x = map(log(i), 0, log(spectrum.length), 0, width);\n * let h = map(spectrum[i], 0, 255, 0, height);\n * let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n * let nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * let mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text('centroid: ', 10, 20);\n * text(round(spectralCentroid)+' Hz', 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function () {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function (s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function (_N) {\n var N = _N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function (octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n (specIndex * nyquist) / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function (_N, _fCtr0) {\n var N = _N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = _fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N)),\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n function freqToFloat(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n }\n function freqToInt(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n }\n function timeToFloat(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n }\n function timeToInt(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.

\n *\n *

This is necessary because Web Audio is processed on a separate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.

\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * let carrier, modulator;\n * let hasStarted = false;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.start();\n * modulator.amp(1);\n * modulator.freq(4);\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-400).add(220) );\n * }\n *\n * function canvasPressed() {\n * userStartAudio();\n * carrier.amp(1.0);\n * if(!hasStarted){\n * carrier.start();\n * hasStarted = true;\n * }\n * }\n *\n * function mouseReleased() {\n * carrier.amp(0);\n * }\n *
\n */\n p5.Signal = function (value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function (_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function (num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function (num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n } else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *

Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).

\n *

Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.

\n *

Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.

\n *\n * @class p5.Envelope\n * @constructor\n * @example\n *
\n * let t1 = 0.1; // attack time in seconds\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n *\n * let env;\n * let triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('tap to play', 20, 20);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope(t1, l1, t2, l2);\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function playSound() {\n * // starting the oscillator ensures that audio is enabled.\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n */\n p5.Envelope = function (t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, 0.001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * let attackTime;\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n * let l3 = 0.2; // release time in seconds\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n *\n * attackTime = map(mouseX, 0, width, 0.0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 20);\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function playSound() {\n * env.set(attackTime, l1, t2, l2, l3);\n *\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function (t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function (aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel =\n typeof sPercent !== 'undefined'\n ? sPercent * (this.aLevel - this.rLevel) + this.rLevel\n : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function (aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function (t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(\n 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)\n );\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function (p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(\n 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)\n );\n this._rampAttackTC =\n this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function () {\n for (var i = 0; i < arguments.length; i++) {\n this.connect(arguments[i]);\n }\n };\n\n /**\n * Set whether the envelope ramp is linear (default) or exponential.\n * Exponential ramps can be useful because we perceive amplitude\n * and frequency logarithmically.\n *\n * @method setExp\n * @for p5.Envelope\n * @param {Boolean} isExp true is exponential, false is linear\n */\n p5.Envelope.prototype.setExp = function (isExp) {\n this.isExponential = isExp;\n };\n\n //helper method to protect against zero values being sent to exponential functions\n p5.Envelope.prototype.checkExpInput = function (value) {\n if (value <= 0) {\n value = 0.00000001;\n }\n return value;\n };\n\n /**\n *

Play tells the envelope to start acting on a given input.\n * If the input is a p5.sound object (i.e. AudioIn, Oscillator,\n * SoundFile), then Envelope will control its output volume.\n * Envelopes can also be used to control any \n * Web Audio Audio Param.

\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * triOsc.start();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * // ensure that audio is enabled\n * userStartAudio();\n *\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + ~~susTime);\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function (unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(valToSet),\n t\n );\n } else {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.aLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.dLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function (unit, secondsFromNow) {\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(valToSet),\n t\n );\n } else {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.rLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value\n * @example\n *
\n * let env, osc, amp;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let attackLevel = 1;\n * let decayLevel = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * // ensures audio is enabled. See also: `userStartAudio`\n * osc.start();\n *\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20);\n * text('tap to play', 10, 20);\n * let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function (unit, secondsFromNow, v1, v2) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 =\n typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n p5.Envelope.prototype.connect = function (unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (\n unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function (num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function (num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function (t1, l1, t2, l2, t3, l3) {\n console.warn(\n 'WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.'\n );\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
\n * let pulse;\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startPulse);\n * background(220);\n *\n * pulse = new p5.Pulse();\n * pulse.amp(0.5);\n * pulse.freq(220);\n * }\n * function startPulse() {\n * pulse.start();\n * pulse.amp(0.5, 0.02);\n * }\n * function mouseReleased() {\n * pulse.amp(0, 0.2);\n * }\n * function draw() {\n * background(220);\n * text('tap to play', 5, 20, width - 20);\n * let w = map(mouseX, 0, width, 0, 1);\n * w = constrain(w, 0, 1);\n * pulse.width(w);\n * text('pulse width: ' + w, 5, height - 20);\n * }\n *
\n */\n p5.Pulse = function (freq, w) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n\n // width of PWM, should be betw 0 to 1.0\n this.w = w || 0;\n\n // create a second oscillator with inverse frequency\n this.osc2 = new p5.SawOsc(freq);\n\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n\n // dc offset\n this.dcOffset = createDCOffset();\n this.dcGain = p5sound.audiocontext.createGain();\n this.dcOffset.connect(this.dcGain);\n this.dcGain.connect(this.output);\n // set delay time based on PWM width\n this.f = freq || 440;\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n\n // disconnect osc2 and connect it to delay, which is connected to output\n this.osc2.disconnect();\n this.osc2.panner.disconnect();\n this.osc2.amp(-1); // inverted amplitude\n this.osc2.output.connect(this.dNode);\n this.dNode.connect(this.output);\n\n this.output.gain.value = 1;\n this.output.connect(this.panner);\n };\n\n p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set the width of a Pulse object (an oscillator that implements\n * Pulse Width Modulation).\n *\n * @method width\n * @param {Number} [width] Width between the pulses (0 to 1.0,\n * defaults to 0)\n */\n p5.Pulse.prototype.width = function (w) {\n if (typeof w === 'number') {\n if (w <= 1.0 && w >= 0.0) {\n this.w = w;\n // set delay time based on PWM width\n\n // var mW = map(this.w, 0, 1.0, 0, 1/this.f);\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n }\n\n this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n } else {\n w.connect(this.dNode.delayTime);\n var sig = new p5.SignalAdd(-0.5);\n sig.setInput(w);\n sig = sig.mult(-1);\n sig = sig.mult(1.7);\n sig.connect(this.dcGain.gain);\n }\n };\n\n p5.Pulse.prototype.start = function (f, time) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.setValueAtTime(freq, now);\n this.oscillator.type = type;\n this.oscillator.connect(this.output);\n this.oscillator.start(t + now);\n\n // set up osc2\n this.osc2.oscillator = p5sound.audiocontext.createOscillator();\n this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);\n this.osc2.oscillator.type = type;\n this.osc2.oscillator.connect(this.osc2.output);\n this.osc2.start(t + now);\n this.freqNode = [\n this.oscillator.frequency,\n this.osc2.oscillator.frequency,\n ];\n\n // start dcOffset, too\n this.dcOffset = createDCOffset();\n this.dcOffset.connect(this.dcGain);\n this.dcOffset.start(t + now);\n\n // if LFO connections depend on these oscillators\n if (this.mods !== undefined && this.mods.frequency !== undefined) {\n this.mods.frequency.connect(this.freqNode[0]);\n this.mods.frequency.connect(this.freqNode[1]);\n }\n this.started = true;\n this.osc2.started = true;\n }\n };\n\n p5.Pulse.prototype.stop = function (time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n if (this.osc2.oscillator) {\n this.osc2.oscillator.stop(t + now);\n }\n this.dcOffset.stop(t + now);\n this.started = false;\n this.osc2.started = false;\n }\n };\n\n p5.Pulse.prototype.freq = function (val, rampTime = 0, tFromNow = 0) {\n if (typeof val === 'number') {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var currentFreq = this.oscillator.frequency.value;\n this.oscillator.frequency.cancelScheduledValues(now);\n this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n this.osc2.oscillator.frequency.cancelScheduledValues(now);\n this.osc2.oscillator.frequency.setValueAtTime(\n currentFreq,\n now + tFromNow\n );\n this.osc2.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n\n if (this.freqMod) {\n this.freqMod.output.disconnect();\n this.freqMod = null;\n }\n } else if (val.output) {\n val.output.disconnect();\n val.output.connect(this.oscillator.frequency);\n val.output.connect(this.osc2.oscillator.frequency);\n this.freqMod = val;\n }\n };\n\n // inspiration: http://webaudiodemos.appspot.com/oscilloscope/\n function createDCOffset() {\n var ac = p5sound.audiocontext;\n var buffer = ac.createBuffer(1, 2048, ac.sampleRate);\n var data = buffer.getChannelData(0);\n for (var i = 0; i < 2048; i++) data[i] = 1.0;\n var bufferSource = ac.createBufferSource();\n bufferSource.buffer = buffer;\n bufferSource.loop = true;\n return bufferSource;\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // generate noise buffers\n const _whiteNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var whiteBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = whiteBuffer.getChannelData(0);\n for (var i = 0; i < bufferSize; i++) {\n noiseData[i] = Math.random() * 2 - 1;\n }\n whiteBuffer.type = 'white';\n return whiteBuffer;\n })();\n\n const _pinkNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var pinkBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = pinkBuffer.getChannelData(0);\n var b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.969 * b2 + white * 0.153852;\n b3 = 0.8665 * b3 + white * 0.3104856;\n b4 = 0.55 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.016898;\n noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n noiseData[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n pinkBuffer.type = 'pink';\n return pinkBuffer;\n })();\n\n const _brownNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var brownBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = brownBuffer.getChannelData(0);\n var lastOut = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n noiseData[i] = (lastOut + 0.02 * white) / 1.02;\n lastOut = noiseData[i];\n noiseData[i] *= 3.5;\n }\n brownBuffer.type = 'brown';\n return brownBuffer;\n })();\n\n /**\n * Noise is a type of oscillator that generates a buffer with random values.\n *\n * @class p5.Noise\n * @extends p5.Oscillator\n * @constructor\n * @param {String} type Type of noise can be 'white' (default),\n * 'brown' or 'pink'.\n */\n p5.Noise = function (type) {\n var assignType;\n p5.Oscillator.call(this);\n delete this.f;\n delete this.freq;\n delete this.oscillator;\n\n if (type === 'brown') {\n assignType = _brownNoiseBuffer;\n } else if (type === 'pink') {\n assignType = _pinkNoiseBuffer;\n } else {\n assignType = _whiteNoiseBuffer;\n }\n this.buffer = assignType;\n };\n\n p5.Noise.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set type of noise to 'white', 'pink' or 'brown'.\n * White is the default.\n *\n * @method setType\n * @param {String} [type] 'white', 'pink' or 'brown'\n */\n p5.Noise.prototype.setType = function (type) {\n switch (type) {\n case 'white':\n this.buffer = _whiteNoiseBuffer;\n break;\n case 'pink':\n this.buffer = _pinkNoiseBuffer;\n break;\n case 'brown':\n this.buffer = _brownNoiseBuffer;\n break;\n default:\n this.buffer = _whiteNoiseBuffer;\n }\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.start(now + 0.01);\n }\n };\n\n p5.Noise.prototype.getType = function () {\n return this.buffer.type;\n };\n\n p5.Noise.prototype.start = function () {\n if (this.started) {\n this.stop();\n }\n this.noise = p5sound.audiocontext.createBufferSource();\n this.noise.buffer = this.buffer;\n this.noise.loop = true;\n this.noise.connect(this.output);\n var now = p5sound.audiocontext.currentTime;\n this.noise.start(now);\n this.started = true;\n };\n\n p5.Noise.prototype.stop = function () {\n var now = p5sound.audiocontext.currentTime;\n if (this.noise) {\n this.noise.stop(now);\n this.started = false;\n }\n };\n\n p5.Noise.prototype.dispose = function () {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.noise) {\n this.noise.disconnect();\n this.stop(now);\n }\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n }\n this.output = null;\n this.panner = null;\n this.buffer = null;\n this.noise = null;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // an array of input sources\n p5sound.inputSources = [];\n\n /**\n *

Get audio from an input, i.e. your computer's microphone.

\n *\n *

Turn the mic on/off with the start() and stop() methods. When the mic\n * is on, its volume can be measured with getLevel or by connecting an\n * FFT object.

\n *\n *

If you want to hear the AudioIn, use the .connect() method.\n * AudioIn does not connect to p5.sound output by default to prevent\n * feedback.

\n *\n *

Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.

\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * let mic;\n *\n * function setup(){\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(userStartAudio);\n * textAlign(CENTER);\n * mic = new p5.AudioIn();\n * mic.start();\n * }\n *\n * function draw(){\n * background(0);\n * fill(255);\n * text('tap to start', width/2, 20);\n *\n * micLevel = mic.getLevel();\n * let y = height - micLevel * height;\n * ellipse(width/2, y, 10, 10);\n * }\n *
\n */\n p5.AudioIn = function (errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables access.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (\n !window.MediaStreamTrack ||\n !window.navigator.mediaDevices ||\n !window.navigator.mediaDevices.getUserMedia\n ) {\n errorCallback\n ? errorCallback()\n : window.alert(\n 'This browser does not support MediaStreamTrack and mediaDevices'\n );\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method.
\n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function (successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false,\n },\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices\n .getUserMedia(constraints)\n .then(function (stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch(function (err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function () {\n if (this.stream) {\n this.stream.getTracks().forEach(function (track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers).
\n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function (unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers.
\n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel().
\n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function (smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0.
\n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function (vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(\n currentVol,\n p5sound.audiocontext.currentTime\n );\n this.output.gain.linearRampToValueAtTime(\n vol,\n rampTime + p5sound.audiocontext.currentTime\n );\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for \n * MediaDevices.enumerateDevices() - Web APIs | MDN\n * and it returns a Promise.\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise(function (resolve, reject) {\n window.navigator.mediaDevices\n .enumerateDevices()\n .then(function (devices) {\n p5sound.inputSources = devices.filter(function (device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch(function (error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error(\n 'This browser does not support MediaStreamTrack.getSources()'\n );\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * \n * navigator.mediaDevices.enumerateDevices()\n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.setSource = function (num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.

\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * let eq, soundFile\n * let eqBandIndex = 0;\n * let eqBandNames = ['lows', 'mids', 'highs'];\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(toggleSound);\n *\n * eq = new p5.EQ(eqBandNames.length);\n * soundFile.disconnect();\n * eq.process(soundFile);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('filtering ', 50, 25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(eqBandNames[eqBandIndex], 50, 55);\n *\n * fill(255);\n * textSize(9);\n *\n * if (!soundFile.isPlaying()) {\n * text('tap to play', 50, 80);\n * } else {\n * text('tap to filter next band', 50, 80)\n * }\n * }\n *\n * function toggleSound() {\n * if (!soundFile.isPlaying()) {\n * soundFile.play();\n * } else {\n * eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n * }\n *\n * for (let i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * // filter the band we want to filter\n * eq.bands[eqBandIndex].gain(-40);\n * }\n *
\n */\n p5.EQ = function (_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? (factor = Math.pow(2, 3)) : (factor = 2);\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = 0.01;\n } else if (i === 0) {\n freq = 100;\n res = 0.1;\n } else if (i === 1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n } else {\n freq = this.bands[i - 1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i > 0) {\n this.bands[i - 1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize - 1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function () {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i += 2) {\n this.bands[i / 2].freq(arguments[i]);\n this.bands[i / 2].gain(arguments[i + 1]);\n }\n } else {\n console.error(\n 'Argument mismatch. .set() should be called with ' +\n this.bands.length * 2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)'\n );\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function (freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function (freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function () {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function () {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function () {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function () {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\n p5.Panner3D = function () {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include
\n * [Panning Model](https://www.w3.org/TR/webaudio/#idl-def-PanningModelType)\n * : \"equal power\" or \"HRTF\"
\n * [DistanceModel](https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType)\n * : \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n };\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function (src) {\n src.connect(this.input);\n };\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function (xVal, yVal, zVal, time) {\n this.positionX(xVal, time);\n this.positionY(yVal, time);\n this.positionZ(zVal, time);\n return [\n this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value,\n ];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function (xVal, yVal, zVal, time) {\n this.orientX(xVal, time);\n this.orientY(yVal, time);\n this.orientZ(zVal, time);\n return [\n this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value,\n ];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function (maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function (maxDistance) {\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function (rolloffFactor) {\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // /**\n // * listener is a class that can construct both a Spatial Panner\n // * and a Spatial Listener. The panner is based on the\n // * Web Audio Spatial Panner Node\n // * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n // * This panner is a spatial processing node that allows audio to be positioned\n // * and oriented in 3D space.\n // *\n // * The Listener modifies the properties of the Audio Context Listener.\n // * Both objects types use the same methods. The default is a spatial panner.\n // *\n // * p5.Panner3D - Constructs a Spatial Panner
\n // * p5.Listener3D - Constructs a Spatial Listener
\n // *\n // * @class listener\n // * @constructor\n // * @return {Object} p5.Listener3D Object\n // *\n // * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n // * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n // * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n // * @param {String} [type] [Specify construction of a spatial panner or listener]\n // */\n\n p5.Listener3D = function (type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n };\n\n // /**\n // * Connect an audio sorce\n // * @param {Object} src Input source\n // */\n p5.Listener3D.prototype.process = function (src) {\n src.connect(this.input);\n };\n // /**\n // * Set the X,Y,Z position of the Panner\n // * @param {[Number]} xVal\n // * @param {[Number]} yVal\n // * @param {[Number]} zVal\n // * @param {[Number]} time\n // * @return {[Array]} [Updated x, y, z values as an array]\n // */\n p5.Listener3D.prototype.position = function (xVal, yVal, zVal, time) {\n this.positionX(xVal, time);\n this.positionY(yVal, time);\n this.positionZ(zVal, time);\n return [\n this.listener.positionX.value,\n this.listener.positionY.value,\n this.listener.positionZ.value,\n ];\n };\n\n // /**\n // * Getter and setter methods for position coordinates\n // * @return {Number} [updated coordinate value]\n // */\n p5.Listener3D.prototype.positionX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n // cannot define method when class definition is commented\n // /**\n // * Overrides the listener orient() method because Listener has slightly\n // * different params. In human terms, Forward vectors are the direction the\n // * nose is pointing. Up vectors are the direction of the top of the head.\n // *\n // * @method orient\n // * @param {Number} xValF Forward vector X direction\n // * @param {Number} yValF Forward vector Y direction\n // * @param {Number} zValF Forward vector Z direction\n // * @param {Number} xValU Up vector X direction\n // * @param {Number} yValU Up vector Y direction\n // * @param {Number} zValU Up vector Z direction\n // * @param {Number} time\n // * @return {Array} All orienation params\n // */\n p5.Listener3D.prototype.orient = function (\n xValF,\n yValF,\n zValF,\n xValU,\n yValU,\n zValU,\n time\n ) {\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n\n return [\n this.listener.forwardX.value,\n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value,\n ];\n };\n\n p5.Listener3D.prototype.orientForward = function (xValF, yValF, zValF, time) {\n this.forwardX(xValF, time);\n this.forwardY(yValF, time);\n this.forwardZ(zValF, time);\n\n return [\n this.listener.forwardX,\n this.listener.forwardY,\n this.listener.forwardZ,\n ];\n };\n\n p5.Listener3D.prototype.orientUp = function (xValU, yValU, zValU, time) {\n this.upX(xValU, time);\n this.upY(yValU, time);\n this.upZ(zValU, time);\n\n return [this.listener.upX, this.listener.upY, this.listener.upZ];\n };\n // /**\n // * Getter and setter methods for orient coordinates\n // * @return {Number} [updated coordinate value]\n // */\n p5.Listener3D.prototype.forwardX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n\n return p5.Listener3D;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * default value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * osc = new p5.Oscillator('square');\n * osc.amp(0.5);\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime (in seconds), feedback, filter frequency\n * delay.process(osc, 0.12, .7, 2300);\n *\n * cnv.mousePressed(oscStart);\n * }\n *\n * function oscStart() {\n * osc.start();\n * }\n *\n * function mouseReleased() {\n * osc.stop();\n * }\n *
\n */\n p5.Delay = function () {\n Effect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @for p5.Delay\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n * @for p5.Delay\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(\n 1200,\n this.ac.currentTime\n );\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function (src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error(\n 'Delay Time exceeds maximum delay time of ' +\n this._maxDelay +\n ' second.'\n );\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function (t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n } else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function (f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n } else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n } else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function (freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function (t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch (t) {\n case 'pingPong':\n this._rightFilter.setType(this._leftFilter.biquad.type);\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * }\n *\n * function draw() {\n * let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n * // 1 = all reverb, 0 = no reverb\n * reverb.drywet(dryWet);\n *\n * background(220);\n * text('tap to play', 10, 20);\n * text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n * }\n *\n * function playSound() {\n * soundFile.play();\n * }\n *
\n */\n\n p5.Reverb = function () {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function () {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function () {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function (audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function (src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function (seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function () {\n var rate = this.ac.sampleRate;\n var length = rate * this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *

p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.

\n *\n *

Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.

\n *\n *

Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.

\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function (path, callback, errorCallback) {\n p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n } else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function (path, callback, errorCallback) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n var self = this;\n var cReverb = new p5.Convolver(\n path,\n function (buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n },\n errorCallback\n );\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function (\n _path,\n callback,\n errorCallback\n ) {\n var path = p5.prototype._checkFileFormats(_path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function () {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(\n request.response,\n function (buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function () {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg =\n 'Unable to load ' +\n self.url +\n '. The request status was: ' +\n request.status +\n ' (' +\n request.statusText +\n ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function () {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg =\n 'There was no response from the server at ' +\n self.url +\n '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the convolver.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *\n *
\n */\n p5.Convolver.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function (path, callback, errorCallback) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function (\n path,\n callback,\n errorCallback\n ) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number).
\n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function (id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function () {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function () {\n this.clock = new Clock({\n callback: this.ontick.bind(this),\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function () {};\n };\n\n p5.Metro.prototype.ontick = function (tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function (thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function (thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (\n phraseArray[bNum] !== 0 &&\n (self.metroTicks < phraseArray.length || !thisPhrase.looping)\n ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function (bpm, rampTime = 0) {\n var beatTime = 60 / (bpm * this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function () {\n return (this.clock.getRate() / this.tatums) * 60;\n };\n\n p5.Metro.prototype._init = function () {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function (part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function (part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function (tatums) {\n this.tatums = 1 / tatums / 4; // lowest possible division of a beat\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function (bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *

A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.

\n *\n *

Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.

\n *\n *

The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).

\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n * let mySound, myPhrase, myPart;\n * let pattern = [1,0,0,2,0,2,0,0];\n *\n * function preload() {\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * text('tap to play', width/2, height/2);\n * textAlign(CENTER, CENTER);\n *\n * myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n * myPart = new p5.Part();\n * myPart.addPhrase(myPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function onEachStep(time, playbackRate) {\n * mySound.rate(playbackRate);\n * mySound.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n * myPart.start();\n * }\n *
\n */\n p5.Phrase = function (name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *

A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.

\n *\n *

See p5.Phrase for more about musical timing.

\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * let box, drum, myPart;\n * let boxPat = [1,0,0,2,0,2,0,0];\n * let drumPat = [0,1,1,0,2,0,1,0];\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * textAlign(CENTER, CENTER);\n * text('tap to play', width/2, height/2);\n *\n * let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n *\n * myPart.start();\n * }\n *
\n */\n p5.Part = function (steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function () {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function (tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function () {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function (time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function (time) {\n this.looping = true;\n // rest onended function\n this.onended = function () {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function () {\n this.looping = false;\n // rest onended function\n this.onended = function () {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function (time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function (time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function (name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function (name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function (name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function (name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function (time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function (callback) {\n this.callback = callback;\n };\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function () {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function () {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function () {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function () {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function () {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function () {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function () {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function () {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function () {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function () {\n var self = this;\n this.parts.forEach(function (part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function (i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function (bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time (if a number) or beats (if a string, following Tone.Time convention) for each iteration of the loop. Defaults to 1 second.\n *\n * @example\n *
\n * let synth, soundLoop;\n * let notePattern = [60, 62, 64, 67, 69, 72];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * colorMode(HSB);\n * background(0, 0, 86);\n * text('tap to start/stop', 10, 20);\n *\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * let intervalInSeconds = 0.2;\n * soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n *\n * synth = new p5.MonoSynth();\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * if (soundLoop.isPlaying) {\n * soundLoop.stop();\n * } else {\n * // start the loop\n * soundLoop.start();\n * }\n * }\n *\n * function onSoundLoop(timeFromNow) {\n * let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n * let note = midiToFreq(notePattern[noteIndex]);\n * synth.play(note, 0.5, timeFromNow);\n * background(noteIndex * 360 / notePattern.length, 50, 100);\n * }\n *
\n */\n p5.SoundLoop = function (callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n callback: function (time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);\n }\n },\n frequency: this._calcFreq(),\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n /**\n * Synchronize loops. Use this method to start two or more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function (otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function () {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function () {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return (\n (this._bpm / 60 / this._convertNotation(this._interval)) *\n (this._timeSignature / 4)\n );\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function (value) {\n var type = value.slice(-1);\n value = Number(value.slice(0, -1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn(\n 'Specified interval is not formatted correctly. See Tone.js ' +\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time'\n );\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function (value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function (value) {\n return this._timeSignature / value;\n };\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get: function () {\n return this._bpm;\n },\n set: function (bpm) {\n if (!this.musicalTimeMode) {\n console.warn(\n 'Changing the BPM in \"seconds\" mode has no effect. ' +\n 'BPM is only relevant in musicalTimeMode ' +\n 'when the interval is specified as a string ' +\n '(\"2n\", \"4n\", \"1m\"...etc)'\n );\n }\n this._bpm = bpm;\n this._update();\n },\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get: function () {\n return this._timeSignature;\n },\n set: function (timeSig) {\n if (!this.musicalTimeMode) {\n console.warn(\n 'Changing the timeSignature in \"seconds\" mode has no effect. ' +\n 'BPM is only relevant in musicalTimeMode ' +\n 'when the interval is specified as a string ' +\n '(\"2n\", \"4n\", \"1m\"...etc)'\n );\n }\n this._timeSignature = timeSig;\n this._update();\n },\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get: function () {\n return this._interval;\n },\n set: function (interval) {\n this.musicalTimeMode = typeof interval === 'number' ? false : true;\n this._interval = interval;\n this._update();\n },\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get: function () {\n return this.clock.ticks;\n },\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n 'use strict';\n\n var Effect = require('effect');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n p5.Compressor = function () {\n Effect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n this.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n };\n\n p5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.process = function (\n src,\n attack,\n knee,\n ratio,\n threshold,\n release\n ) {\n src.connect(this.input);\n this.set(attack, knee, ratio, threshold, release);\n };\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (\n attack,\n knee,\n ratio,\n threshold,\n release\n ) {\n if (typeof attack !== 'undefined') {\n this.attack(attack);\n }\n if (typeof knee !== 'undefined') {\n this.knee(knee);\n }\n if (typeof ratio !== 'undefined') {\n this.ratio(ratio);\n }\n if (typeof threshold !== 'undefined') {\n this.threshold(threshold);\n }\n if (typeof release !== 'undefined') {\n this.release(release);\n }\n };\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time) {\n var t = time || 0;\n if (typeof attack === 'number') {\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.attack.linearRampToValueAtTime(\n attack,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time) {\n var t = time || 0;\n if (typeof knee === 'number') {\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.knee.linearRampToValueAtTime(\n knee,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time) {\n var t = time || 0;\n if (typeof ratio === 'number') {\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.ratio.linearRampToValueAtTime(\n ratio,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time) {\n var t = time || 0;\n if (typeof threshold === 'number') {\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.threshold.linearRampToValueAtTime(\n threshold,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time) {\n var t = time || 0;\n if (typeof release === 'number') {\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.release.linearRampToValueAtTime(\n release,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction = function () {\n return this.compressor.reduction.value;\n };\n\n p5.Compressor.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n };\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n const p5sound = require('master');\n const { convertToWav, safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n const ac = p5sound.audiocontext;\n\n /**\n *

Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().

\n *

The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.

\n *\n * @class p5.SoundRecorder\n * @constructor\n * @example\n *
\n * let mic, recorder, soundFile;\n * let state = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * textAlign(CENTER, CENTER);\n *\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('tap to record', width/2, height/2);\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', width/2, height/2);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Done! Tap to play and download', width/2, height/2, width - 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function () {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n const workletBufferSize = safeBufferSize(1024);\n\n this._workletNode = new AudioWorkletNode(\n ac,\n processorNames.recorderProcessor,\n {\n outputChannelCount: [this._outputChannels],\n processorOptions: {\n numInputChannels: this._inputChannels,\n bufferSize: workletBufferSize,\n },\n }\n );\n\n this._workletNode.port.onmessage = function (event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer),\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function () {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function (unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function (sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function (buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n } else if (sFile) {\n this._callback = function (buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function () {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function () {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *

PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *

\n *

\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *

\n *

\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *

\n *\n *

threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.

\n *\n *

\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *

\n *\n *

\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *

\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n *\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 10;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n *\n * // p5.PeakDetect requires a p5.FFT\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n * }\n *\n * function draw() {\n * background(0);\n * text('click to play/pause', width/2, height/2);\n *\n * // peakDetect accepts an fft post-analysis\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * if ( peakDetect.isDetected ) {\n * ellipseWidth = 50;\n * } else {\n * ellipseWidth *= 0.95;\n * }\n *\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // toggle play/stop when canvas is clicked\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * }\n * }\n *
\n */\n p5.PeakDetect = function (freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function () {};\n };\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function (fftObject) {\n var nrg = (this.energy = fftObject.getEnergy(this.f1, this.f2) / 255);\n if (nrg > this.cutoff && nrg > this.threshold && nrg - this.penergy > 0) {\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function (callback, val) {\n var self = this;\n\n self._onPeak = function () {\n callback(self.energy, val);\n };\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * let sound1,sound2;\n * let sound1Gain, sound2Gain, masterGain;\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * // create a 'master' gain to which we will connect both soundfiles\n * masterGain = new p5.Gain();\n * masterGain.connect();\n * sound1.disconnect(); // diconnect from p5 output\n * sound1Gain = new p5.Gain(); // setup a gain node\n * sound1Gain.setInput(sound1); // connect the first sound to its input\n * sound1Gain.connect(masterGain); // connect its output to the 'master'\n * sound2.disconnect();\n * sound2Gain = new p5.Gain();\n * sound2Gain.setInput(sound2);\n * sound2Gain.connect(masterGain);\n * }\n * function startSound() {\n * sound1.loop();\n * sound2.loop();\n * loop();\n * }\n * function mouseReleased() {\n * sound1.stop();\n * sound2.stop();\n * }\n * function draw(){\n * background(220);\n * textAlign(CENTER);\n * textSize(11);\n * fill(0);\n * if (!sound1.isPlaying()) {\n * text('tap and drag to play', width/2, height/2);\n * return;\n * }\n * // map the horizontal position of the mouse to values useable for volume * control of sound1\n * var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n * var sound2Volume = 1-sound1Volume;\n * sound1Gain.amp(sound1Volume);\n * sound2Gain.amp(sound2Volume);\n * // map the vertical position of the mouse to values useable for 'master * volume control'\n * var masterVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n * masterGain.amp(masterVolume);\n * text('master', width/2, height - masterVolume * height * 0.9)\n * fill(255, 0, 255);\n * textAlign(LEFT);\n * text('sound1', 5, height - sound1Volume * height * 0.9);\n * textAlign(RIGHT);\n * text('sound2', width - 5, height - sound2Volume * height * 0.9);\n * }\n *
\n */\n\n p5.Gain = function () {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n p5.Gain.prototype.setInput = function (src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for (; i < numSamples; ++i) {\n x = (i * 2) / numSamples - 1;\n curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function (amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n }\n if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n }\n if (typeof oversample === 'undefined') {\n oversample = '2x';\n }\n if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function (src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function (amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function () {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function () {\n return this.waveShaperNode.oversample;\n };\n\n p5.Distortion.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file diff --git a/lib/p5.sound.min.js b/lib/p5.sound.min.js index fe65a81f..856e73d3 100644 --- a/lib/p5.sound.min.js +++ b/lib/p5.sound.min.js @@ -1,3 +1,3 @@ -/** [p5.sound] Version: 0.3.12 - 2020-01-06 */ - !function(n){var i={};function o(t){if(i[t])return i[t].exports;var e=i[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,o),e.l=!0,e.exports}o.m=n,o.c=i,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)o.d(n,i,function(t){return e[t]}.bind(null,i));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=31)}([function(t,e,n){var i;void 0===(i=function(){"use strict";function c(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var i=this._searchAfter(t);i&&(this.cancelScheduledValues(t),i.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):i.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.linearRampToValueAtTime(t,n),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,n),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),n=this._searchBefore(t),i=this._initial;if(null===n)i=this._initial;else if(n.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(n.time);o=null===r?this._initial:r.value,i=this._exponentialApproach(n.time,o,n.value,n.constant,t)}else i=n.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(n.time,n.value,n.duration,t):null===e?n.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(n.time,n.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(n.time,n.value,e.time,e.value,t):n.value;return i},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,n,i,o){return n+(e-n)*Math.exp(-(o-t)/i)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,n,i,o){return e+(o-t)/(n-t)*(i-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,n,i,o){return(e=Math.max(this._minOutput,e))*Math.pow(i/e,(o-t)/(n-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,n,i){var o=e.length;if(t+n<=i)return e[o-1];if(i<=t)return e[0];var r=(i-t)/n,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,i))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var e=n(4);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,n,i){t.connect(this.input),this.set(e,n,i)},p5.Filter.prototype.set=function(t,e,n){t&&this.freq(t,n),e&&this.res(e,n)},p5.Filter.prototype.freq=function(t,e){var n=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var n=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var n=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){var i,o;i=[n(0),n(7),n(25),n(2),n(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,i))||(t.exports=o)},function(i,o,r){"use strict";(function(t){var e,n;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(12),r(0)],void 0===(n=function(i,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var n=t;return t instanceof p5.Element?n=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(n=t.map(function(t){return t.elt})),i(o,n,e)},o}.apply(o,e))||(i.exports=n)}).call(this,r(34))},function(t,e,n){var i,o;i=[n(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var n=t.split(/\W+/),i=0;ithis.memory){var n=this.length-this.memory;this._timeline.splice(0,n)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,n=this._timeline.length,i=n;if(0t)return o;r.time>t?i=o:r.time=t;)n--;return this._iterate(e,n+1),this},e.Timeline.prototype.forEachAtTime=function(e,n){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&n(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(3),n(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(2),n(3),n(5)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(14),n(66),n(18),n(12)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var n=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=n.time,this.isUndef(n.offset)||(this.ticks=n.offset),this.emit("start",n.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",n.time)):e===o.State.Paused&&this.emit("pause",n.time)}var i=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(i),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,i))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var n=i(1),e=i(29),r=i(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),n.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,n,i){this.triggerAttack(t,e,~~n),this.triggerRelease(~~n+(i||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e,n){n=~~n;var i=r(t),o=e||.1;this.oscillator.freq(i,0,n),this.env.ramp(this.output.gain,n,o)},p5.MonoSynth.prototype.triggerRelease=function(t){t=t||0;this.env.ramp(this.output.gain,t,0)},p5.MonoSynth.prototype.setADSR=function(t,e,n,i){this.env.setADSR(t,e,n,i)},Object.defineProperties(p5.MonoSynth.prototype,{attack:{get:function(){return this.env.aTime},set:function(t){this.env.setADSR(t,this.env.dTime,this.env.sPercent,this.env.rTime)}},decay:{get:function(){return this.env.dTime},set:function(t){this.env.setADSR(this.env.aTime,t,this.env.sPercent,this.env.rTime)}},sustain:{get:function(){return this.env.sPercent},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,t,this.env.rTime)}},release:{get:function(){return this.env.rTime},set:function(t){this.env.setADSR(this.env.aTime,this.env.dTime,this.env.sPercent,t)}}}),p5.MonoSynth.prototype.amp=function(t,e){var n=e||0;return void 0!==t&&this.oscillator.amp(t,n),this.oscillator.amp().value},p5.MonoSynth.prototype.connect=function(t){var e=t||n.input;this.output.connect(e.input?e.input:e)},p5.MonoSynth.prototype.disconnect=function(){this.output&&this.output.disconnect()},p5.MonoSynth.prototype.dispose=function(){e.prototype.dispose.apply(this),this.env&&this.env.dispose(),this.oscillator&&this.oscillator.dispose()}}.call(e,i,e,t))||(t.exports=n)},function(t,e,i){"use strict";var n;void 0===(n=function(){var n=i(1);return p5.AudioVoice=function(){this.ac=n.audiocontext,this.output=this.ac.createGain(),this.connect(),n.soundArray.push(this)},p5.AudioVoice.prototype.play=function(t,e,n,i){},p5.AudioVoice.prototype.triggerAttack=function(t,e,n){},p5.AudioVoice.prototype.triggerRelease=function(t){},p5.AudioVoice.prototype.amp=function(t,e){},p5.AudioVoice.prototype.connect=function(t){var e=t||n.input;this.output.connect(e.input?e.input:e)},p5.AudioVoice.prototype.disconnect=function(){this.output.disconnect()},p5.AudioVoice.prototype.dispose=function(){this.output&&(this.output.disconnect(),delete this.output)},p5.AudioVoice}.call(e,i,e,t))||(t.exports=n)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var c=n(1),h=n(14),l=n(6).noteToFreq;p5.PolySynth=function(t,e){this.audiovoices=[],this.notes={},this._newest=0,this._oldest=0,this.maxVoices=e||8,this.AudioVoice=void 0===t?p5.MonoSynth:t,this._voicesInUse=new h(0),this.output=c.audiocontext.createGain(),this.connect(),this._allocateVoices(),c.soundArray.push(this)},p5.PolySynth.prototype._allocateVoices=function(){for(var t=0;t= this._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; 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);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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; 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);'},function(t,e,n){"use strict";var i;function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}void 0===(i=function(t){var a=n(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var n=e||0,i=a.currentTime+n;this.stereoPanner.pan.linearRampToValueAtTime(t,i)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,n){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var n=t||0,i=e||void 0;this.isPlaying()&&(this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,n,i))},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,n=e.length/t,i=~~(n/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var n=this.buffer.numberOfChannels,i=0;ie){var r=t[o],s=new c(r,o);n[o]=s,o+=6e3}o++}return n}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+n[s])/2:n[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){t=t||3;var n=[],i={lo:(e=e||15.625)/Math.pow(2,1/(2*t)),ctr:e,hi:e*Math.pow(2,1/(2*t))};n.push(i);for(var o=c.audiocontext.sampleRate/2;i.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,i&&(this._leftFilter.freq(i),this._rightFilter.freq(i))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){n.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,i,e,t))||(t.exports=n)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var p=n(11),e=n(4);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,n,i){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),n&&(this._decay=n),i&&(this._reverse=i),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,n){var i=!1;t&&(this._seconds=t,i=!0),e&&(this._decay=e),n&&(this._reverse=n),i&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,n=this.ac.sampleRate,i=n*this._seconds,o=this._decay,r=this.ac.createBuffer(2,i,n),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var n in o=t,i.parts)i.parts[n]&&i.parts[n].setBPM(t,e)},p5.Phrase=function(t,e,n){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=n},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),i.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,n){var i;if(3===arguments.length)i=new p5.Phrase(t,e,n);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";i=t}this.phrases.push(i),i.sequence.length>this.length&&(this.length=i.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var n in this.phrases)this.phrases[n].name===t&&(this.phrases[n].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var i=this._searchAfter(t);i&&(this.cancelScheduledValues(t),i.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):i.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.linearRampToValueAtTime(t,n),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,n),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),n=this._searchBefore(t),i=this._initial;if(null===n)i=this._initial;else if(n.type===u.TimelineSignal.Type.Target){var o,r=this._events.getBefore(n.time);o=null===r?this._initial:r.value,i=this._exponentialApproach(n.time,o,n.value,n.constant,t)}else i=n.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(n.time,n.value,n.duration,t):null===e?n.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(n.time,n.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(n.time,n.value,e.time,e.value,t):n.value;return i},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,n,i,o){return n+(e-n)*Math.exp(-(o-t)/i)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,n,i,o){return e+(o-t)/(n-t)*(i-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,n,i,o){return(e=Math.max(this._minOutput,e))*Math.pow(i/e,(o-t)/(n-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,n,i){var o=e.length;if(t+n<=i)return e[o-1];if(i<=t)return e[0];var r=(i-t)/n,s=Math.floor((o-1)*r),a=Math.ceil((o-1)*r),u=e[s],p=e[a];return a===s?u:this._linearInterpolate(s,u,a,p,r*(o-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,i))||(t.exports=o)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var e=n(5);return p5.Filter=function(t){e.call(this),this.biquad=this.ac.createBiquadFilter(),this.input.connect(this.biquad),this.biquad.connect(this.wet),t&&this.setType(t),this._on=!0,this._untoggledType=this.biquad.type},p5.Filter.prototype=Object.create(e.prototype),p5.Filter.prototype.process=function(t,e,n,i){t.connect(this.input),this.set(e,n,i)},p5.Filter.prototype.set=function(t,e,n){t&&this.freq(t,n),e&&this.res(e,n)},p5.Filter.prototype.freq=function(t,e){var n=e||0;return t<=0&&(t=1),"number"==typeof t?(this.biquad.frequency.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.frequency.exponentialRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.frequency),this.biquad.frequency.value},p5.Filter.prototype.res=function(t,e){var n=e||0;return"number"==typeof t?(this.biquad.Q.value=t,this.biquad.Q.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.Q.linearRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.Q),this.biquad.Q.value},p5.Filter.prototype.gain=function(t,e){var n=e||0;return"number"==typeof t?(this.biquad.gain.value=t,this.biquad.gain.cancelScheduledValues(this.ac.currentTime+.01+n),this.biquad.gain.linearRampToValueAtTime(t,this.ac.currentTime+.02+n)):t&&t.connect(this.biquad.gain),this.biquad.gain.value},p5.Filter.prototype.toggle=function(){return this._on=!this._on,!0===this._on?this.biquad.type=this._untoggledType:!1===this._on&&(this.biquad.type="allpass"),this._on},p5.Filter.prototype.setType=function(t){this.biquad.type=t,this._untoggledType=this.biquad.type},p5.Filter.prototype.dispose=function(){e.prototype.dispose.apply(this),this.biquad&&(this.biquad.disconnect(),delete this.biquad)},p5.LowPass=function(){p5.Filter.call(this,"lowpass")},p5.LowPass.prototype=Object.create(p5.Filter.prototype),p5.HighPass=function(){p5.Filter.call(this,"highpass")},p5.HighPass.prototype=Object.create(p5.Filter.prototype),p5.BandPass=function(){p5.Filter.call(this,"bandpass")},p5.BandPass.prototype=Object.create(p5.Filter.prototype),p5.Filter}.call(e,n,e,t))||(t.exports=i)},function(t,e,n){var i,o;i=[n(0),n(7),n(25),n(2),n(9)],void 0===(o=function(e){"use strict";return e.Subtract=function(t){this.createInsOuts(2,0),this._sum=this.input[0]=this.output=new e.Gain,this._neg=new e.Negate,this._param=this.input[1]=new e.Signal(t),this._param.chain(this._neg,this._sum)},e.extend(e.Subtract,e.Signal),e.Subtract.prototype.dispose=function(){return e.prototype.dispose.call(this),this._neg.dispose(),this._neg=null,this._sum.disconnect(),this._sum=null,this._param.dispose(),this._param=null,this},e.Subtract}.apply(e,i))||(t.exports=o)},function(i,o,r){"use strict";(function(t){var e,n;t.TONE_SILENCE_VERSION_LOGGING=!0,e=[r(35),r(11),r(0)],void 0===(n=function(i,t,e){var o=new window.AudioContext;return e.context.dispose(),e.setContext(o),p5.prototype.getAudioContext=function(){return o},p5.prototype.userStartAudio=function(t,e){var n=t;return t instanceof p5.Element?n=t.elt:t instanceof Array&&t[0]instanceof p5.Element&&(n=t.map(function(t){return t.elt})),i(o,n,e)},o}.apply(o,e))||(i.exports=n)}).call(this,r(34))},function(t,e,n){var i,o;i=[n(0)],void 0===(o=function(s){"use strict";return s.Emitter=function(){this._events={}},s.extend(s.Emitter),s.Emitter.prototype.on=function(t,e){for(var n=t.split(/\W+/),i=0;ithis.memory){var n=this.length-this.memory;this._timeline.splice(0,n)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,n=this._timeline.length,i=n;if(0t)return o;r.time>t?i=o:r.time=t;)n--;return this._iterate(e,n+1),this},e.Timeline.prototype.forEachAtTime=function(e,n){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&n(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(3),n(2)],void 0===(o=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(2),n(3),n(4)],void 0===(o=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,i))||(t.exports=o)},function(t,e,n){var i,o;i=[n(0),n(14),n(66),n(18),n(11)],void 0===(o=function(o){"use strict";return o.Clock=function(){o.Emitter.call(this);var t=this.optionsObject(arguments,["callback","frequency"],o.Clock.defaults);this.callback=t.callback,this._nextTick=0,this._lastState=o.State.Stopped,this.frequency=new o.TimelineSignal(t.frequency,o.Type.Frequency),this._readOnly("frequency"),this.ticks=0,this._state=new o.TimelineState(o.State.Stopped),this._boundLoop=this._loop.bind(this),this.context.on("tick",this._boundLoop)},o.extend(o.Clock,o.Emitter),o.Clock.defaults={callback:o.noOp,frequency:1,lookAhead:"auto"},Object.defineProperty(o.Clock.prototype,"state",{get:function(){return this._state.getValueAtTime(this.now())}}),o.Clock.prototype.start=function(t,e){return t=this.toSeconds(t),this._state.getValueAtTime(t)!==o.State.Started&&this._state.add({state:o.State.Started,time:t,offset:e}),this},o.Clock.prototype.stop=function(t){return t=this.toSeconds(t),this._state.cancel(t),this._state.setStateAtTime(o.State.Stopped,t),this},o.Clock.prototype.pause=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)===o.State.Started&&this._state.setStateAtTime(o.State.Paused,t),this},o.Clock.prototype._loop=function(){for(var t=this.now()+this.context.lookAhead+this.context.updateInterval+2*this.context.lag;t>this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var n=this._state.get(this._nextTick);e===o.State.Started?(this._nextTick=n.time,this.isUndef(n.offset)||(this.ticks=n.offset),this.emit("start",n.time,this.ticks)):e===o.State.Stopped?(this.ticks=0,this.emit("stop",n.time)):e===o.State.Paused&&this.emit("pause",n.time)}var i=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===o.State.Started&&(this.callback(i),this.ticks++))}},o.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},o.Clock.prototype.dispose=function(){o.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},o.Clock}.apply(e,i))||(t.exports=o)},function(t,e,i){"use strict";var n;void 0===(n=function(t){var n=i(1),e=i(29),r=i(6).noteToFreq;p5.MonoSynth=function(){e.call(this),this.oscillator=new p5.Oscillator,this.env=new p5.Envelope,this.env.setRange(1,0),this.env.setExp(!0),this.setADSR(.02,.25,.05,.35),this.oscillator.disconnect(),this.oscillator.connect(this.output),this.env.disconnect(),this.env.setInput(this.output.gain),this.oscillator.output.gain.value=1,this.oscillator.start(),this.connect(),n.soundArray.push(this)},p5.MonoSynth.prototype=Object.create(p5.AudioVoice.prototype),p5.MonoSynth.prototype.play=function(t,e,n,i){this.triggerAttack(t,e,~~n),this.triggerRelease(~~n+(i||.15))},p5.MonoSynth.prototype.triggerAttack=function(t,e){var n=2= 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; 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);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _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, [{\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; ++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; 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);'},function(t,e,n){"use strict";var i;void 0===(i=function(t){var a=n(1).audiocontext;void 0!==a.createStereoPanner?(p5.Panner=function(t,e){this.stereoPanner=this.input=a.createStereoPanner(),t.connect(this.stereoPanner),this.stereoPanner.connect(e)},p5.Panner.prototype.pan=function(t,e){var n=e||0,i=a.currentTime+n;this.stereoPanner.pan.linearRampToValueAtTime(t,i)},p5.Panner.prototype.inputChannels=function(){},p5.Panner.prototype.connect=function(t){this.stereoPanner.connect(t)},p5.Panner.prototype.disconnect=function(){this.stereoPanner&&this.stereoPanner.disconnect()}):(p5.Panner=function(t,e,n){this.input=a.createGain(),t.connect(this.input),this.left=a.createGain(),this.right=a.createGain(),this.left.channelInterpretation="discrete",this.right.channelInterpretation="discrete",1this.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var n=t||0,i=e||void 0;this.isPlaying()&&(this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,n,i))},p5.SoundFile.prototype.channels=function(){return this.buffer.numberOfChannels},p5.SoundFile.prototype.sampleRate=function(){return this.buffer.sampleRate},p5.SoundFile.prototype.frames=function(){return this.buffer.length},p5.SoundFile.prototype.getPeaks=function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,n=e.length/t,i=~~(n/10)||1,o=e.numberOfChannels,r=new Float32Array(Math.round(t)),s=0;sr[u])&&(r[u]=h)}return r}},p5.SoundFile.prototype.reverseBuffer=function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/p.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var n=this.buffer.numberOfChannels,i=0;ie){var r=t[o],s=new c(r,o);n[o]=s,o+=6e3}o++}return n}function m(t){if(isFinite(t)&&0!==t){for(;t<90;)t*=2;for(;180t[r].hi&&r++,o[r]=void 0!==o[r]?(o[r]+n[s])/2:n[s]}return o},p5.FFT.prototype.getOctaveBands=function(t,e){var n=t||3,i=e||15.625,o=[],r={lo:i/Math.pow(2,1/(2*n)),ctr:i,hi:i*Math.pow(2,1/(2*n))};o.push(r);for(var s=c.audiocontext.sampleRate/2;r.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(r,this.ac.currentTime),this._leftGain.gain.value=o,this._rightGain.gain.value=o,i&&(this._leftFilter.freq(i),this._rightFilter.freq(i))},p5.Delay.prototype.delayTime=function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))},p5.Delay.prototype.feedback=function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value},p5.Delay.prototype.filter=function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)},p5.Delay.prototype.setType=function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}},p5.Delay.prototype.dispose=function(){n.prototype.dispose.apply(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}.call(e,i,e,t))||(t.exports=n)},function(t,e,n){"use strict";var i;void 0===(i=function(t){var p=n(12),e=n(5);p5.Reverb=function(){e.call(this),this._initConvolverNode(),this.input.gain.value=.5,this._seconds=3,this._decay=2,this._reverse=!1,this._buildImpulse()},p5.Reverb.prototype=Object.create(e.prototype),p5.Reverb.prototype._initConvolverNode=function(){this.convolverNode=this.ac.createConvolver(),this.input.connect(this.convolverNode),this.convolverNode.connect(this.wet)},p5.Reverb.prototype._teardownConvolverNode=function(){this.convolverNode&&(this.convolverNode.disconnect(),delete this.convolverNode)},p5.Reverb.prototype._setBuffer=function(t){this._teardownConvolverNode(),this._initConvolverNode(),this.convolverNode.buffer=t},p5.Reverb.prototype.process=function(t,e,n,i){t.connect(this.input);var o=!1;e&&(this._seconds=e,o=!0),n&&(this._decay=n),i&&(this._reverse=i),o&&this._buildImpulse()},p5.Reverb.prototype.set=function(t,e,n){var i=!1;t&&(this._seconds=t,i=!0),e&&(this._decay=e),n&&(this._reverse=n),i&&this._buildImpulse()},p5.Reverb.prototype._buildImpulse=function(){var t,e,n=this.ac.sampleRate,i=n*this._seconds,o=this._decay,r=this.ac.createBuffer(2,i,n),s=r.getChannelData(0),a=r.getChannelData(1);for(e=0;e=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}p5.prototype.setBPM=function(t,e){for(var n in o=t,i.parts)i.parts[n]&&i.parts[n].setBPM(t,e)},p5.Phrase=function(t,e,n){this.phraseStep=0,this.name=t,this.callback=e,this.sequence=n},p5.Part=function(t,e){this.length=t||0,this.partStep=0,this.phrases=[],this.isPlaying=!1,this.noLoop(),this.tatums=e||.0625,this.metro=new p5.Metro,this.metro._init(),this.metro.beatLength(this.tatums),this.metro.setBPM(o),i.parts.push(this),this.callback=function(){}},p5.Part.prototype.setBPM=function(t,e){this.metro.setBPM(t,e)},p5.Part.prototype.getBPM=function(){return this.metro.getBPM()},p5.Part.prototype.start=function(t){if(!this.isPlaying){this.isPlaying=!0,this.metro.resetSync(this);var e=t||0;this.metro.start(e)}},p5.Part.prototype.loop=function(t){this.looping=!0,this.onended=function(){this.partStep=0};var e=t||0;this.start(e)},p5.Part.prototype.noLoop=function(){this.looping=!1,this.onended=function(){this.stop()}},p5.Part.prototype.stop=function(t){this.partStep=0,this.pause(t)},p5.Part.prototype.pause=function(t){this.isPlaying=!1;var e=t||0;this.metro.stop(e)},p5.Part.prototype.addPhrase=function(t,e,n){var i;if(3===arguments.length)i=new p5.Phrase(t,e,n);else{if(!(t instanceof p5.Phrase))throw"invalid input. addPhrase accepts name, callback, array or a p5.Phrase";i=t}this.phrases.push(i),i.sequence.length>this.length&&(this.length=i.sequence.length)},p5.Part.prototype.removePhrase=function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)},p5.Part.prototype.getPhrase=function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]},p5.Part.prototype.replaceSequence=function(t,e){for(var n in this.phrases)this.phrases[n].name===t&&(this.phrases[n].sequence=e)},p5.Part.prototype.incrementStep=function(t){this.partStepthis.cutoff&&e>this.threshold&&0 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *

\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\n\ndefine(['audiocontext'], function (audiocontext) {\n // Master contains the master sound output.\n var Master = function() {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function() {\n return p5sound.output.gain.value;\n };\n\n /**\n *

Scale the output of all sound in this sketch

\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *

How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.

\n *\n *

If no value is provided, returns a Web Audio API Gain Node

\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function(vol, rampTime, tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n // a silent connection to the DesinationNode\n // which will ensure that anything connected to it\n // will not be garbage collected\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5.
\n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function(vol, rampTime, tFromNow){\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + .001);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + .001);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function(){\n if (arguments.length>0){\n this.connect(arguments[0]);\n for(var i=1;i\n * let midiNotes = [60, 64, 67, 72];\n * let noteIndex = 0;\n * let midiVal, freq;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * osc = new p5.TriOsc();\n * env = new p5.Envelope();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 10, 20);\n * if (midiVal) {\n * text('MIDI: ' + midiVal, 10, 40);\n * text('Freq: ' + freq, 10, 60);\n * }\n * }\n *\n * function startSound() {\n * // see also: userStartAudio();\n * osc.start();\n *\n * midiVal = midiNotes[noteIndex % midiNotes.length];\n * freq = midiToFreq(midiVal);\n * osc.freq(freq);\n * env.ramp(osc, 0, 1.0, 0);\n *\n * noteIndex++;\n * }\n * \n */\n var midiToFreq = p5.prototype.midiToFreq = function(m) {\n return 440 * Math.pow(2, (m-69)/12.0);\n };\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function(note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = {A:21, B:23, C:24, D:26, E:28, F:29, G:31};\n var value = wholeNotes[ note[0].toUpperCase() ];\n var octave = ~~note.slice(-1);\n value += 12 * (octave -1);\n\n switch(note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('sound loaded! tap to play', 10, 20, width - 20);\n * cnv.mousePressed(function() {\n * mySound.play();\n * });\n * }\n *
\n */\n p5.prototype.soundFormats = function() {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function() {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function(paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3','wav','ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (p5.prototype.isFileSupported(extTest)) {\n path = path;\n }\n else {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (var i = 0; i 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7FFF * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length;) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n function safeBufferSize(idealBufferSize) {\n let bufferSize = idealBufferSize;\n\n // if the AudioWorkletNode is actually a ScriptProcessorNode created via polyfill,\n // make sure that our chosen buffer size isn't smaller than the buffer size automatically\n // selected by the polyfill\n // reference: https://github.com/GoogleChromeLabs/audioworklet-polyfill/issues/13#issuecomment-425014930\n let tempAudioWorkletNode = new AudioWorkletNode(p5sound.audiocontext, processorNames.soundFileProcessor);\n if (tempAudioWorkletNode instanceof ScriptProcessorNode) {\n bufferSize = tempAudioWorkletNode.bufferSize;\n }\n tempAudioWorkletNode.disconnect();\n tempAudioWorkletNode = null;\n\n return bufferSize;\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq,\n safeBufferSize: safeBufferSize\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
    \n\t\t *
  • Numbers, which will be taken literally as the time (in seconds).
  • \n\t\t *
  • Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
  • \n\t\t *
  • TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
  • \n\t\t *
  • Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
  • \n\t\t *
  • Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
  • \n\t\t *
  • Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
  • \n\t\t *
  • No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
  • \n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
    \n\t\t * \t
  • \"4n\" = quarter note
  • \n\t\t * \t
  • \"2m\" = two measures
  • \n\t\t * \t
  • \"8t\" = eighth-note triplet
  • \n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor'\n};\n","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function(name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n var splitStack = tempStack.split('\\n');\n splitStack = splitStack.filter(function(ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *

A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:

\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff.
\n * p5.HighPass:\n * The opposite of a lowpass filter.
\n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range.
\n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * let fft, noise, filter;\n *\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(makeNoise);\n * fill(255, 0, 255);\n *\n * filter = new p5.BandPass();\n * noise = new p5.Noise();\n * noise.disconnect();\n * noise.connect(filter);\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(220);\n *\n * // set the BandPass frequency based on mouseX\n * let freq = map(mouseX, 0, width, 20, 10000);\n * freq = constrain(freq, 0, 22050);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * let spectrum = fft.analyze();\n * noStroke();\n * for (let i = 0; i < spectrum.length; i++) {\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n * if (!noise.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n * }\n * }\n *\n * function makeNoise() {\n * // see also: `userStartAudio()`\n * noise.start();\n * noise.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * noise.amp(0, 0.2);\n * }\n *\n *
\n */\n p5.Filter = function (type) {\n\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n\t */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function(src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function(freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function(freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function(res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(res, this.ac.currentTime + 0.02 + t);\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function(gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(gain, this.ac.currentTime + 0.02 + t);\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function() {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function(t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function() {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function() {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function() {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function() {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (StartAudioContext, Context, Tone) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *

Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .

\n *\n *

Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.

\n *\n * @for p5\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
\n */\n p5.prototype.getAudioContext = function() {\n return audiocontext;\n };\n\n\n /**\n *

It is not only a good practice to give users control over starting\n * audio. This policy is enforced by many web browsers, including iOS and\n * Google Chrome, which create the Web Audio API's\n * Audio Context\n * in a suspended state.

\n *\n *

In these browser-specific policies, sound will not play until a user\n * interaction event (i.e. mousePressed()) explicitly resumes\n * the AudioContext, or starts an audio node. This can be accomplished by\n * calling start() on a p5.Oscillator,\n * play() on a p5.SoundFile, or simply\n * userStartAudio().

\n *\n *

userStartAudio() starts the AudioContext on a user\n * gesture. The default behavior will enable audio on any\n * mouseUp or touchEnd event. It can also be placed in a specific\n * interaction function, such as mousePressed() as in the\n * example below. This method utilizes\n * StartAudioContext\n * , a library by Yotam Mann (MIT Licence, 2016).

\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext\n * has started\n * @return {Promise} Returns a Promise that resolves when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * // mimics the autoplay policy\n * getAudioContext().suspend();\n *\n * let mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has resumed\n * mySynth.play('A6');\n * }\n * function draw() {\n * background(220);\n * textAlign(CENTER, CENTER);\n * text(getAudioContext().state, width/2, height/2);\n * }\n * function mousePressed() {\n * userStartAudio();\n * }\n *
\n */\n p5.prototype.userStartAudio = function(elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element ) {\n elt = elements.map(function(e) { return e.elt});\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).

\n *\n *

Set the type of oscillation with setType(), or by instantiating a\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\n *

\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * let osc, playing, freq, amp;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator('sine');\n * }\n *\n * function draw() {\n * background(220)\n * freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n * amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n *\n * text('tap to play', 20, 20);\n * text('freq: ' + freq, 20, 40);\n * text('amp: ' + amp, 20, 60);\n *\n * if (playing) {\n * // smooth the transitions by 0.1 seconds\n * osc.freq(freq, 0.1);\n * osc.amp(amp, 0.1);\n * }\n * }\n *\n * function playOscillator() {\n * // starting an oscillator on a user gesture will enable audio\n * // in browsers that have a strict autoplay policy.\n * // See also: userStartAudio();\n * osc.start();\n * playing = true;\n * }\n *\n * function mouseReleased() {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * }\n *
\n */\n p5.Oscillator = function(freq, type) {\n if (typeof freq === 'string') {\n var f = type;\n type = freq;\n freq = f;\n } if (typeof type === 'number') {\n var f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator.\n *\n * Starting an oscillator on a user gesture will enable audio in browsers\n * that have a strict autoplay policy, including Chrome and most mobile\n * devices. See also: `userStartAudio()`.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function(time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function(vol, rampTime, tFromNow) {\n var self = this;\n if (typeof vol === 'number') {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n\n else if (vol) {\n vol.connect(self.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator(300);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playOscillator() {\n * osc.start();\n * osc.amp(0.5);\n * // start at 700Hz\n * osc.freq(700);\n * // ramp to 60Hz over 0.7 seconds\n * osc.freq(60, 0.7);\n * osc.amp(0, 0.1, 0.7);\n * }\n *
\n */\n p5.Oscillator.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var t = now + tFromNow + rampTime;\n // var currentFreq = this.oscillator.frequency.value;\n // this.oscillator.frequency.cancelScheduledValues(now);\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0 ) {\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push( val );\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function() {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function(type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function() {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n }\n else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function() {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function(p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1/this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function(o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i+1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i-1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length-1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function(freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds.\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (note, velocity, secondsFromNow, susTime) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n var secondsFromNow = ~~secondsFromNow;\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow) {\n var secondsFromNow = secondsFromNow || 0;\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack,decay,sustain,release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n 'attack': {\n get : function() {\n return this.env.aTime;\n },\n set : function(attack) {\n this.env.setADSR(attack, this.env.dTime,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'decay': {\n get : function() {\n return this.env.dTime;\n },\n set : function(decay) {\n this.env.setADSR(this.env.aTime, decay,\n this.env.sPercent, this.env.rTime);\n }\n },\n 'sustain': {\n get : function() {\n return this.env.sPercent;\n },\n set : function(sustain) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n sustain, this.env.rTime);\n }\n },\n 'release': {\n get : function() {\n return this.env.rTime;\n },\n set : function(release) {\n this.env.setADSR(this.env.aTime, this.env.dTime,\n this.env.sPercent, release);\n }\n },\n });\n\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function(vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function() {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n\n});\n","'use strict';\ndefine(function() {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n\t this.ac = p5sound.audiocontext;\n\t this.output = this.ac.createGain();\n\t this.connect();\n\t p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (note, velocity, secondsFromNow, sustime) {\n };\n\n p5.AudioVoice.prototype.triggerAttack = function (note, velocity, secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {\n };\n\n p5.AudioVoice.prototype.amp = function(vol, rampTime) {\n };\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function(unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function() {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function() {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n **/\n p5.PolySynth = function(audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n\t * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function() {\n for(var i = 0; i< this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (note,velocity, secondsFromNow, susTime) {\n var susTime = susTime || 1;\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (note,a,d,s,r,timeFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var timeFromNow = timeFromNow || 0;\n var t = now + timeFromNow\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].setADSR(a,d,s,r);\n };\n\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function(a,d,s,r) {\n this.audiovoices.forEach(function(voice) {\n voice.setADSR(a,d,s,r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (_note, _velocity, secondsFromNow) {\n //this value goes to the audiovoices which handle their own scheduling\n var secondsFromNow = ~~secondsFromNow;\n\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(this.audiovoices[this._oldest].oscillator.freq().value);\n this.noteRelease(oldestNote);\n this._oldest = ( this._oldest + 1 ) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal = this._voicesInUse._searchBefore(acTime) === null ? 0 : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = 1 / this._voicesInUse.getValueAtTime(acTime) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n this.audiovoices[currentVoice].triggerAttack(note, velocity, secondsFromNow);\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function(time, value) {\n if(this._voicesInUse._searchAfter(time) === null) {\n return;\n } else{\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note,secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function(voice) {\n voice.triggerRelease(tFromNow)\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(~~this._voicesInUse.getValueAtTime(t).value, 1);\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[ this.notes[note].getValueAtTime(t) ].triggerRelease(tFromNow);\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest = this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function() {\n this.audiovoices.forEach(function(voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this._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; 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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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; 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);\"","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if(typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function() {};\n\n p5.Panner.prototype.connect = function(obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function(input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function(val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos(v*Math.PI/2);\n var leftVal = Math.sin(v * Math.PI/2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function(numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof(this.splitter === 'undefined')) {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function(obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n\n const CustomError = require('errorHandler');\n const p5sound = require('master');\n const ac = p5sound.audiocontext;\n const { midiToFreq, convertToWav, safeBufferSize } = require('helpers');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *

SoundFile object with a path to a file.

\n *\n *

The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.

\n *\n *

To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.

\n *\n *

Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.

\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile = function(paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n }\n else if(typeof paths === 'object') {\n if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function() {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function() {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.prototype.loadSound = function(path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined' ) {\n window.alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n\n var self = this;\n var s = new p5.SoundFile(path, function() {\n if(typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, onerror, whileLoading);\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function(callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener('progress', function(evt) {\n self._updateProgress(evt);\n }, false);\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(request.response,\n // success decoding buffer:\n function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n if (!self.panner) return;\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url + '. The request status was: ' +\n request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n\n request.send();\n }\n else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function() {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function(buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function(e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function(evt) {\n if (evt.lengthComputable) {\n var percentComplete = evt.loaded / evt.total * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function() {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function(startTime, rate, amp, _cueStart, duration) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >=0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else { throw 'start time out of range'; }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration = duration <= this.buffer.duration - cueStart ? duration : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n\n };\n\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * let mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * noFill();\n * rect(0, height/2, width - 1, height/2 - 1);\n * rect(0, 0, width - 1, height/2);\n * textAlign(CENTER, CENTER);\n * fill(20);\n * text('restart', width/2, 1 * height/4);\n * text('sustain', width/2, 3 * height/4);\n * }\n * function canvasPressed() {\n * if (mouseX < height/2) {\n * mySound.playMode('restart');\n * } else {\n * mySound.playMode('sustain');\n * }\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function(str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n * let soundFile;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.pause = function(startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n * @example\n *
\n * let soundFile;\n * let loopStart = 0.5;\n * let loopDuration = 0.2;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.loop = function(startTime, rate, amp, loopStart, duration) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function(bool) {\n if (bool === true) {\n this._looping = true;\n }\n else if (bool === false) {\n this._looping = false;\n }\n else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function() {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function() {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function() {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function(timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n }\n else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function(_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (!!bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch(e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function(vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n }\n else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function() {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n * let ballX = 0;\n * let soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * ballX = constrain(mouseX, 0, width);\n * ellipse(ballX, height/2, 20, 20);\n * }\n *\n * function canvasPressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * let panning = map(ballX, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function(pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function() {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * let mySound;\n *\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * }\n * function canvasPressed() {\n * mySound.loop();\n * }\n * function mouseReleased() {\n * mySound.pause();\n * }\n * function draw() {\n * background(220);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * let playbackRate = map(mouseY, 0.1, height, 2, 0);\n * playbackRate = constrain(playbackRate, 0.01, 4);\n * mySound.rate(playbackRate);\n *\n * line(0, mouseY, width, mouseY);\n * text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function(playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n }\n\n else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n }\n\n else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(Math.abs(playbackRate), now);\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function(num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function() {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function() {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function() {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of a soundfile that is currently playing to a\n * new position and a new duration, in seconds.\n * If none are given, will reset the file to play entire duration\n * from start to finish. To set the position of a soundfile that is\n * not currently playing, use the `play` or `loop` methods.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function(cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n }\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function() {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function() {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function() {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function(length) {\n\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width*5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i*sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j+= sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n }\n\n else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * let drum;\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function canvasPressed() {\n * drum.stop();\n * drum.reverseBuffer();\n * drum.play();\n * }\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function() {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (this.isPlaying() && currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function(callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function() {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch(e) {\n console.warn('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if ( this.isPlaying() ) {\n try {\n this._counterNode.stop(now);\n } catch(e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function(unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n }\n else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function() {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function() {\n console.warn('p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead');\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function(p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function(buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData( channelNum );\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function(buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer( 1, buffer.length, ac.sampleRate );\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function() {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n const workletBufferSize = safeBufferSize(256);\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(ac, processorNames.soundFileProcessor, {\n processorOptions: { bufferSize: workletBufferSize }\n });\n self._workletNode.port.onmessage = event => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer( self.buffer );\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function() {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function(callback, _initThreshold, _minThreshold, _minPeaks) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function(e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (Object.keys(allPeaks).length < minPeaks && threshold >= minThreshold);\n\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(intervalCounts, filteredBuffer.sampleRate);\n\n // sort top intervals\n var topTempos = groups.sort(function(intA, intB) {\n return intB.count - intA.count;\n\n }).splice(0,5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(allPeaks, topTempos[0].tempo, filteredBuffer.sampleRate, bpmVariance);\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function(amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function(intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function(intervalCount) {\n\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs( 60 / (intervalCount.interval / sampleRate ) );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function(tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return tempoCount.count += intervalCount.count;\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count\n });\n }\n } catch(e) {\n throw e;\n }\n\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(Math.abs( 60 / (peak.intervals[j] / sampleRate) ) );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if ( Math.abs(intervalBPM - tempo) < bpmVariance ) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex/sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function(peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0 ) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90) theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function(callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 10, 20);\n *\n * // schedule calls to changeText\n * mySound.addCue(0, changeText, \"hello\" );\n * mySound.addCue(0.5, changeText, \"hello,\" );\n * mySound.addCue(1, changeText, \"hello, p5!\");\n * mySound.addCue(1.5, changeText, \"hello, p5!!\");\n * mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n * }\n *\n * function changeText(val) {\n * background(220);\n * text(val, 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile.prototype.addCue = function(time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function(id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function() {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function(position) {\n var playbackTime = position/this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0 ; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (~~this._prevUpdateTime <= callbackTime && callbackTime <= playbackTime) {\n\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n\n }\n\n this._prevUpdateTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to download', 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.save('my cool filename');\n * }\n *
\n */\n p5.SoundFile.prototype.save = function(fileName) {\n p5.prototype.saveSound(this, fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * let soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * let httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * let blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function() {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n // delete bufferSourceNode(s) in soundFile.bufferSourceNodes\n // iterate in reverse order because the index changes by splice\n soundFile.bufferSourceNodes.map((_, i) => i).reverse().forEach(function (i) {\n const n = soundFile.bufferSourceNodes[i];\n\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i, 1);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const p5sound = require('master');\n const { safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * let sound, amplitude;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *\n *
\n */\n p5.Amplitude = function(smoothing) {\n\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = safeBufferSize(2048);\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(this.audiocontext, processorNames.amplitudeProcessor, {\n outputChannelCount: [1],\n\n parameterData: { smoothing: smoothing || 0 },\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0,\n numInputChannels: 2,\n bufferSize: this.bufferSize\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n *\n * amplitude = new p5.Amplitude();\n * amplitude.setInput(sound2);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound1.isPlaying() && sound2.isPlaying()) {\n * sound1.stop();\n * sound2.stop();\n * } else {\n * sound1.play();\n * sound2.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function(source, smoothing) {\n\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log('Amplitude input source is not ready! Connecting to master output instead');\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220, 150);\n * textAlign(CENTER);\n * text('tap to play', width/2, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound.isPlaying()) {\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function(channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n }\n else if (this.normalize) {\n return this.volNorm;\n }\n else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function(bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n }\n else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({ name: 'toggleNormalize', normalize: this.normalize });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function(s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n\n});\n","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n /**\n *

FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.

\n *\n *

Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses:
• FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time.
\n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.

\n *\n *

FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.

\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(220);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * let waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(20);\n * for (let i = 0; i < waveform.length; i++){\n * let x = map(i, 0, waveform.length, 0, width);\n * let y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('tap to play', 20, 20);\n * }\n *\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function(smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function() {\n return this.analyser.fftSize / 2;\n },\n set: function(b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true\n },\n smoothing: {\n get: function() {\n return this.analyser.smoothingTimeConstant;\n },\n set: function(s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true\n }\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function(source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function() {\n var bins, mode, normalArray;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n var normalArray = new Array();\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * let osc, fft;\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(startSound);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(220);\n *\n * let freq = map(mouseX, 0, windowWidth, 20, 10000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * if (!osc.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text(round(freq)+'Hz', 10, 20);\n * }\n * }\n *\n * function startSound() {\n * osc.start();\n * osc.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * osc.amp(0, 0.2);\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function() {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n\n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.

\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function(frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function(freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.

\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n * function setup(){\n * cnv = createCanvas(100,100);\n * cnv.mousePressed(userStartAudio);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *function draw() {\n * if (getAudioContext().state !== 'running') {\n * background(220);\n * text('tap here and enable mic to begin', 10, 20, width - 20);\n * return;\n * }\n * let centroidplot = 0.0;\n * let spectralCentroid = 0;\n *\n * background(0);\n * stroke(0,255,0);\n * let spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (let i = 0; i < spectrum.length; i++){\n * let x = map(log(i), 0, log(spectrum.length), 0, width);\n * let h = map(spectrum[i], 0, 255, 0, height);\n * let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n * let nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * let mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text('centroid: ', 10, 20);\n * text(round(spectralCentroid)+' Hz', 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function() {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function(s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function(N) {\n var N = N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function(octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n specIndex * nyquist / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function(N, fCtr0) {\n var N = N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N))\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n var freqToFloat = function(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var freqToInt = function(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToFloat = function(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n };\n var timeToInt = function(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.

\n *\n *

This is necessary because Web Audio is processed on a seprate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.

\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * let carrier, modulator;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * carrier = new p5.Oscillator('sine');\n * carrier.start();\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.start();\n * modulator.amp(1);\n * modulator.freq(4);\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-400).add(220) );\n * }\n *\n * function canvasPressed() {\n * userStartAudio();\n * carrier.amp(1.0);\n * }\n *\n * function mouseReleased() {\n * carrier.amp(0);\n * }\n *
\n */\n p5.Signal = function(value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function(_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function(num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function(num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n }\n else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n\n});\n\n\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *

Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).

\n *

Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.

\n *

Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.

\n *\n * @class p5.Envelope\n * @constructor\n * @example\n *
\n * let t1 = 0.1; // attack time in seconds\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n *\n * let env;\n * let triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('tap to play', 20, 20);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope(t1, l1, t2, l2);\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function playSound() {\n * // starting the oscillator ensures that audio is enabled.\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n */\n p5.Envelope = function(t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, .001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * let attackTime;\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n * let l3 = 0.2; // release time in seconds\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n *\n * attackTime = map(mouseX, 0, width, 0.0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 20);\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function playSound() {\n * env.set(attackTime, l1, t2, l2, l3);\n *\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function(t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function(aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel = typeof sPercent !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function(aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function(t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function(p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(1.0 / this.checkExpInput(1.0 - this._rampHighPercentage));\n this._rampAttackTC = this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function() {\n for (var i = 0; iPlay tells the envelope to start acting on a given input.\n * If the input is a p5.sound object (i.e. AudioIn, Oscillator,\n * SoundFile), then Envelope will control its output volume.\n * Envelopes can also be used to control any \n * Web Audio Audio Param.

\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * triOsc.start();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * // ensure that audio is enabled\n * userStartAudio();\n *\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.play = function(unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n var susTime = susTime || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);\n\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function(unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.aLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.dLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function(unit, secondsFromNow) {\n\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(valToSet), t);\n }\n else\n {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true)\n {\n this.control.exponentialRampToValueAtTime(this.checkExpInput(this.rLevel), t);\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n }\n else\n {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value (optional)\n * @example\n *
\n * let env, osc, amp;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let attackLevel = 1;\n * let decayLevel = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * // ensures audio is enabled. See also: `userStartAudio`\n * osc.start();\n *\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20);\n * text('tap to play', 10, 20);\n * let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function(unit, secondsFromNow, v1, v2) {\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 = typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n\n p5.Envelope.prototype.connect = function(unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function(num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function(num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function(inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function(t1, l1, t2, l2, t3, l3) {\n console.warn('WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.');\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
\n * let pulse;\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startPulse);\n * background(220);\n *\n * pulse = new p5.Pulse();\n * pulse.amp(0.5);\n * pulse.freq(220);\n * }\n * function startPulse() {\n * pulse.start();\n * pulse.amp(0.5, 0.02);\n * }\n * function mouseReleased() {\n * pulse.amp(0, 0.2);\n * }\n * function draw() {\n * background(220);\n * text('tap to play', 5, 20, width - 20);\n * let w = map(mouseX, 0, width, 0, 1);\n * w = constrain(w, 0, 1);\n * pulse.width(w);\n * text('pulse width: ' + w, 5, height - 20);\n * }\n *
\n */\n p5.Pulse = function(freq, w) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n\n // width of PWM, should be betw 0 to 1.0\n this.w = w || 0;\n\n // create a second oscillator with inverse frequency\n this.osc2 = new p5.SawOsc(freq);\n\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n\n // dc offset\n this.dcOffset = createDCOffset();\n this.dcGain = p5sound.audiocontext.createGain();\n this.dcOffset.connect(this.dcGain);\n this.dcGain.connect(this.output);\n // set delay time based on PWM width\n this.f = freq || 440;\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n this.dcGain.gain.value = 1.7*(0.5-this.w);\n\n // disconnect osc2 and connect it to delay, which is connected to output\n this.osc2.disconnect();\n this.osc2.panner.disconnect();\n this.osc2.amp(-1); // inverted amplitude\n this.osc2.output.connect(this.dNode);\n this.dNode.connect(this.output);\n\n this.output.gain.value = 1;\n this.output.connect(this.panner);\n };\n\n p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set the width of a Pulse object (an oscillator that implements\n * Pulse Width Modulation).\n *\n * @method width\n * @param {Number} [width] Width between the pulses (0 to 1.0,\n * defaults to 0)\n */\n p5.Pulse.prototype.width = function(w) {\n if (typeof w === 'number') {\n if (w <= 1.0 && w >= 0.0) {\n this.w = w;\n // set delay time based on PWM width\n\n // var mW = map(this.w, 0, 1.0, 0, 1/this.f);\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n }\n\n this.dcGain.gain.value = 1.7*(0.5-this.w);\n } else {\n w.connect(this.dNode.delayTime);\n var sig = new p5.SignalAdd(-0.5);\n sig.setInput(w);\n sig = sig.mult(-1);\n sig = sig.mult(1.7);\n sig.connect(this.dcGain.gain);\n }\n };\n\n p5.Pulse.prototype.start = function(f, time) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.setValueAtTime(freq, now);\n this.oscillator.type = type;\n this.oscillator.connect(this.output);\n this.oscillator.start(t + now);\n\n // set up osc2\n this.osc2.oscillator = p5sound.audiocontext.createOscillator();\n this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);\n this.osc2.oscillator.type = type;\n this.osc2.oscillator.connect(this.osc2.output);\n this.osc2.start(t + now);\n this.freqNode = [this.oscillator.frequency, this.osc2.oscillator.frequency];\n\n // start dcOffset, too\n this.dcOffset = createDCOffset();\n this.dcOffset.connect(this.dcGain);\n this.dcOffset.start(t + now);\n\n // if LFO connections depend on these oscillators\n if (this.mods !== undefined && this.mods.frequency !== undefined) {\n this.mods.frequency.connect(this.freqNode[0]);\n this.mods.frequency.connect(this.freqNode[1]);\n }\n this.started = true;\n this.osc2.started = true;\n }\n };\n\n p5.Pulse.prototype.stop = function(time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n if (this.osc2.oscillator) {\n this.osc2.oscillator.stop(t + now);\n }\n this.dcOffset.stop(t + now);\n this.started = false;\n this.osc2.started = false;\n }\n };\n\n p5.Pulse.prototype.freq = function(val, rampTime, tFromNow) {\n if (typeof val === 'number') {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var currentFreq = this.oscillator.frequency.value;\n this.oscillator.frequency.cancelScheduledValues(now);\n this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n this.osc2.oscillator.frequency.cancelScheduledValues(now);\n this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n\n if (this.freqMod) {\n this.freqMod.output.disconnect();\n this.freqMod = null;\n }\n\n } else if (val.output) {\n val.output.disconnect();\n val.output.connect(this.oscillator.frequency);\n val.output.connect(this.osc2.oscillator.frequency);\n this.freqMod = val;\n }\n };\n\n // inspiration: http://webaudiodemos.appspot.com/oscilloscope/\n function createDCOffset() {\n var ac = p5sound.audiocontext;\n var buffer=ac.createBuffer(1,2048,ac.sampleRate);\n var data = buffer.getChannelData(0);\n for (var i=0; i<2048; i++)\n data[i]=1.0;\n var bufferSource=ac.createBufferSource();\n bufferSource.buffer=buffer;\n bufferSource.loop=true;\n return bufferSource;\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * Noise is a type of oscillator that generates a buffer with random values.\n *\n * @class p5.Noise\n * @extends p5.Oscillator\n * @constructor\n * @param {String} type Type of noise can be 'white' (default),\n * 'brown' or 'pink'.\n */\n p5.Noise = function(type) {\n var assignType;\n p5.Oscillator.call(this);\n delete this.f;\n delete this.freq;\n delete this.oscillator;\n\n if (type === 'brown') {\n assignType = _brownNoise;\n } else if (type === 'pink') {\n assignType = _pinkNoise;\n } else {\n assignType = _whiteNoise;\n }\n this.buffer = assignType;\n };\n\n p5.Noise.prototype = Object.create(p5.Oscillator.prototype);\n\n // generate noise buffers\n var _whiteNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = whiteBuffer.getChannelData(0);\n for (var i = 0; i < bufferSize; i++) {\n noiseData[i] = Math.random() * 2 - 1;\n }\n whiteBuffer.type = 'white';\n return whiteBuffer;\n })();\n\n var _pinkNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = pinkBuffer.getChannelData(0);\n var b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.96900 * b2 + white * 0.1538520;\n b3 = 0.86650 * b3 + white * 0.3104856;\n b4 = 0.55000 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.0168980;\n noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n noiseData[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n pinkBuffer.type = 'pink';\n return pinkBuffer;\n })();\n\n var _brownNoise = (function() {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n var noiseData = brownBuffer.getChannelData(0);\n var lastOut = 0.0;\n for (var i = 0; i< bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n noiseData[i] = (lastOut + 0.02*white) / 1.02;\n lastOut = noiseData[i];\n noiseData[i] *= 3.5;\n }\n brownBuffer.type = 'brown';\n return brownBuffer;\n })();\n\n /**\n * Set type of noise to 'white', 'pink' or 'brown'.\n * White is the default.\n *\n * @method setType\n * @param {String} [type] 'white', 'pink' or 'brown'\n */\n p5.Noise.prototype.setType = function(type) {\n switch(type) {\n case 'white':\n this.buffer = _whiteNoise;\n break;\n case 'pink':\n this.buffer = _pinkNoise;\n break;\n case 'brown':\n this.buffer = _brownNoise;\n break;\n default:\n this.buffer = _whiteNoise;\n }\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.start(now+.01);\n }\n };\n\n p5.Noise.prototype.getType = function() {\n return this.buffer.type;\n };\n\n p5.Noise.prototype.start = function() {\n if (this.started) {\n this.stop();\n }\n this.noise = p5sound.audiocontext.createBufferSource();\n this.noise.buffer = this.buffer;\n this.noise.loop = true;\n this.noise.connect(this.output);\n var now = p5sound.audiocontext.currentTime;\n this.noise.start(now);\n this.started = true;\n };\n\n p5.Noise.prototype.stop = function() {\n var now = p5sound.audiocontext.currentTime;\n if (this.noise) {\n this.noise.stop(now);\n this.started = false;\n }\n };\n\n p5.Noise.prototype.dispose = function() {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.noise) {\n this.noise.disconnect();\n this.stop(now);\n }\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n }\n this.output = null;\n this.panner = null;\n this.buffer = null;\n this.noise = null;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // an array of input sources\n p5sound.inputSources = [];\n\n /**\n *

Get audio from an input, i.e. your computer's microphone.

\n *\n *

Turn the mic on/off with the start() and stop() methods. When the mic\n * is on, its volume can be measured with getLevel or by connecting an\n * FFT object.

\n *\n *

If you want to hear the AudioIn, use the .connect() method.\n * AudioIn does not connect to p5.sound output by default to prevent\n * feedback.

\n *\n *

Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.

\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * let mic;\n *\n * function setup(){\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(userStartAudio);\n * textAlign(CENTER);\n * mic = new p5.AudioIn();\n * mic.start();\n * }\n *\n * function draw(){\n * background(0);\n * fill(255);\n * text('tap to start', width/2, 20);\n *\n * micLevel = mic.getLevel();\n * let y = height - micLevel * height;\n * ellipse(width/2, y, 10, 10);\n * }\n *
\n */\n p5.AudioIn = function(errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables access.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (!window.MediaStreamTrack || !window.navigator.mediaDevices || !window.navigator.mediaDevices.getUserMedia) {\n errorCallback ? errorCallback() : window.alert('This browser does not support MediaStreamTrack and mediaDevices');\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method.
\n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function(successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false\n }\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices.getUserMedia( constraints )\n .then( function(stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch( function(err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function() {\n if (this.stream) {\n this.stream.getTracks().forEach(function(track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers).
\n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function(unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n }\n else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n }\n else {\n this.output.connect(unit);\n }\n }\n else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers.
\n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel().
\n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function(smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0.
\n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function(vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for and it returns a Promise.\n *\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise( function(resolve, reject) {\n window.navigator.mediaDevices.enumerateDevices()\n .then( function(devices) {\n p5sound.inputSources = devices.filter(function(device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch( function(error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error('This browser does not support MediaStreamTrack.getSources()');\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n *
navigator.mediaDevices.enumerateDevices().
\n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.setSource = function(num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.

\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * let eq, soundFile\n * let eqBandIndex = 0;\n * let eqBandNames = ['lows', 'mids', 'highs'];\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(toggleSound);\n *\n * eq = new p5.EQ(eqBandNames.length);\n * soundFile.disconnect();\n * eq.process(soundFile);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('filtering ', 50, 25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(eqBandNames[eqBandIndex], 50, 55);\n *\n * fill(255);\n * textSize(9);\n *\n * if (!soundFile.isPlaying()) {\n * text('tap to play', 50, 80);\n * } else {\n * text('tap to filter next band', 50, 80)\n * }\n * }\n *\n * function toggleSound() {\n * if (!soundFile.isPlaying()) {\n * soundFile.play();\n * } else {\n * eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n * }\n *\n * for (let i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * // filter the band we want to filter\n * eq.bands[eqBandIndex].gain(-40);\n * }\n *
\n */\n p5.EQ = function(_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? factor = Math.pow(2,3) : factor = 2;\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = .01;\n } else if (i === 0) {\n freq = 100;\n res = .1;\n }\n else if (i===1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n }else {\n freq = this.bands[i-1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i>0) {\n this.bands[i-1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize-1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function() {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i+=2) {\n this.bands[i/2].freq(arguments[i]);\n this.bands[i/2].gain(arguments[i+1]);\n }\n }\n else {\n console.error('Argument mismatch. .set() should be called with ' + this.bands.length*2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)');\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function(freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function(freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function() {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function() {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function() {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function() {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\tp5.Panner3D = function() {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include\n * - panningModel: \"equal power\" or \"HRTF\"\n * - distanceModel: \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n\t};\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function(xVal, yVal, zVal, time) {\n this.orientX(xVal,time);\n this.orientY(yVal,time);\n this.orientZ(zVal,time);\n return [this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.panner.orientationZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function(maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function(maxDistance){\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function(rolloffFactor){\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n\n});\n","'use strict'\n\ndefine(function (require) {\n var p5sound = require('master');\n var Effect = require('effect');\n\n// /**\n// * listener is a class that can construct both a Spatial Panner\n// * and a Spatial Listener. The panner is based on the \n// * Web Audio Spatial Panner Node\n// * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n// * This panner is a spatial processing node that allows audio to be positioned\n// * and oriented in 3D space. \n// *\n// * The Listener modifies the properties of the Audio Context Listener. \n// * Both objects types use the same methods. The default is a spatial panner.\n// *\n// * p5.Panner3D - Constructs a Spatial Panner
\n// * p5.Listener3D - Constructs a Spatial Listener
\n// *\n// * @class listener\n// * @constructor\n// * @return {Object} p5.Listener3D Object\n// *\n// * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n// * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n// * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n// * @param {String} [type] [Specify construction of a spatial panner or listener]\n// */\n \n\tp5.Listener3D = function(type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n\t}; \n\n// /**\n// * Connect an audio sorce\n// * @param {Object} src Input source\n// */\n p5.Listener3D.prototype.process = function(src) {\n src.connect(this.input);\n }\n// /**\n// * Set the X,Y,Z position of the Panner\n// * @param {[Number]} xVal\n// * @param {[Number]} yVal\n// * @param {[Number]} zVal\n// * @param {[Number]} time\n// * @return {[Array]} [Updated x, y, z values as an array]\n// */\n p5.Listener3D.prototype.position = function(xVal, yVal, zVal, time) {\n this.positionX(xVal,time);\n this.positionY(yVal,time);\n this.positionZ(zVal,time);\n return [this.listener.positionX.value, \n this.listener.positionY.value,\n this.listener.positionZ.value];\n };\n\n// /**\n// * Getter and setter methods for position coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.positionX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.positionZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n// cannot define method when class definition is commented\n// /**\n// * Overrides the listener orient() method because Listener has slightly\n// * different params. In human terms, Forward vectors are the direction the \n// * nose is pointing. Up vectors are the direction of the top of the head.\n// *\n// * @method orient\n// * @param {Number} xValF Forward vector X direction\n// * @param {Number} yValF Forward vector Y direction\n// * @param {Number} zValF Forward vector Z direction\n// * @param {Number} xValU Up vector X direction\n// * @param {Number} yValU Up vector Y direction\n// * @param {Number} zValU Up vector Z direction\n// * @param {Number} time \n// * @return {Array} All orienation params\n// */\n p5.Listener3D.prototype.orient = function(xValF, yValF, zValF, \n xValU, yValU, zValU, time) {\n\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n \n return [this.listener.forwardX.value, \n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value];\n };\n\n\n p5.Listener3D.prototype.orientForward = function(xValF, yValF, zValF, time) {\n this.forwardX(xValF,time);\n this.forwardY(yValF,time);\n this.forwardZ(zValF,time);\n\n return [this.listener.forwardX, \n this.listener.forwardY,\n this.listener.forwardZ];\n };\n\n p5.Listener3D.prototype.orientUp = function(xValU, yValU, zValU, time) {\n this.upX(xValU,time);\n this.upY(yValU,time);\n this.upZ(zValU,time);\n\n return [this.listener.upX, \n this.listener.upY,\n this.listener.upZ];\n };\n// /**\n// * Getter and setter methods for orient coordinates\n// * @return {Number} [updated coordinate value]\n// */\n p5.Listener3D.prototype.forwardX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.forwardZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function(xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(xVal, this.ac.currentTime + 0.02 + t);\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function(yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(yVal, this.ac.currentTime + 0.02 + t);\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function(zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(zVal, this.ac.currentTime + 0.02 + t);\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n \n return p5.Listener3D;\n\n});","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * default value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * osc = new p5.Oscillator('square');\n * osc.amp(0.5);\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime (in seconds), feedback, filter frequency\n * delay.process(osc, 0.12, .7, 2300);\n *\n * cnv.mousePressed(oscStart);\n * }\n *\n * function oscStart() {\n * osc.start();\n * }\n *\n * function mouseReleased() {\n * osc.stop();\n * }\n *
\n */\n p5.Delay = function() {\n \tEffect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @for p5.Delay\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n * @for p5.Delay\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n\n\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function(src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function(t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n }\n\n else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function(f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n }\n else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function(freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function(t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch(t) {\n case 'pingPong':\n this._rightFilter.setType( this._leftFilter.biquad.type );\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function() {\n\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * }\n *\n * function draw() {\n * let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n * // 1 = all reverb, 0 = no reverb\n * reverb.drywet(dryWet);\n *\n * background(220);\n * text('tap to play', 10, 20);\n * text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n * }\n *\n * function playSound() {\n * soundFile.play();\n * }\n *
\n */\n\n\n p5.Reverb = function() {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function() {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function() {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function(audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function(src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function(seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function() {\n var rate = this.ac.sampleRate;\n var length = rate*this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *

p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.

\n *\n *

Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.

\n *\n *

Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.

\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function(path, callback, errorCallback) {\n \t p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n }\n else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n var self = this;\n var cReverb = new p5.Convolver(path, function(buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n }, errorCallback);\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function(path, callback, errorCallback) {\n var path = p5.prototype._checkFileFormats(path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function() {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(request.response,\n function(buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function() {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'Unable to load ' + self.url +\n '. The request status was: ' + request.status + ' (' + request.statusText + ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function() {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg = 'There was no response from the server at ' + self.url + '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(msg +'\\n The error stack trace includes: \\n' + err.stack);\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the convolver.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *\n *
\n */\n p5.Convolver.prototype.process = function(src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function(path, callback, errorCallback) {\n // if loading locally without a server\n if (window.location.origin.indexOf('file://') > -1 && window.cordova === 'undefined') {\n alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number).
\n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function(id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function() {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function() {\n this.clock = new Clock({\n 'callback': this.ontick.bind(this)\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function() {};\n };\n\n p5.Metro.prototype.ontick = function(tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function(thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function(thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (phraseArray[bNum] !== 0 && (self.metroTicks < phraseArray.length || !thisPhrase.looping) ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function(bpm, rampTime) {\n var beatTime = 60 / (bpm*this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n var rampTime = rampTime || 0;\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function() {\n return this.clock.getRate() / this.tatums * 60;\n };\n\n p5.Metro.prototype._init = function() {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function(part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function(part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function(tatums) {\n this.tatums = 1/tatums / 4; // lowest possible division of a beat\n };\n\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function(require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function(bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *

A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.

\n *\n *

Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.

\n *\n *

The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).

\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n * let mySound, myPhrase, myPart;\n * let pattern = [1,0,0,2,0,2,0,0];\n *\n * function preload() {\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * text('tap to play', width/2, height/2);\n * textAlign(CENTER, CENTER);\n *\n * myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n * myPart = new p5.Part();\n * myPart.addPhrase(myPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function onEachStep(time, playbackRate) {\n * mySound.rate(playbackRate);\n * mySound.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n * myPart.start();\n * }\n *
\n */\n p5.Phrase = function(name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *

A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.

\n *\n *

See p5.Phrase for more about musical timing.

\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * let box, drum, myPart;\n * let boxPat = [1,0,0,2,0,2,0,0];\n * let drumPat = [0,1,1,0,2,0,1,0];\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * textAlign(CENTER, CENTER);\n * text('tap to play', width/2, height/2);\n *\n * let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n *\n * myPart.start();\n * }\n *
\n */\n p5.Part = function(steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function() {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function(tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function() {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function(time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function(time) {\n this.looping = true;\n // rest onended function\n this.onended = function() {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function() {\n this.looping = false;\n // rest onended function\n this.onended = function() {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function(time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function(time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function(name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function(name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function(name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function(time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function(callback) {\n this.callback = callback;\n };\n\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function() {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function() {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function() {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function() {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function() {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function() {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function() {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function() {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function() {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function() {\n var self = this;\n this.parts.forEach(function(part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function(i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function(bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time (if a number) or beats (if a string, following Tone.Time convention) for each iteration of the loop. Defaults to 1 second.\n *\n * @example\n *
\n * let synth, soundLoop;\n * let notePattern = [60, 62, 64, 67, 69, 72];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * colorMode(HSB);\n * background(0, 0, 86);\n * text('tap to start/stop', 10, 20);\n *\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * let intervalInSeconds = 0.2;\n * soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n *\n * synth = new p5.MonoSynth();\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * if (soundLoop.isPlaying) {\n * soundLoop.stop();\n * } else {\n * // start the loop\n * soundLoop.start();\n * }\n * }\n *\n * function onSoundLoop(timeFromNow) {\n * let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n * let note = midiToFreq(notePattern[noteIndex]);\n * synth.play(note, 0.5, timeFromNow);\n * background(noteIndex * 360 / notePattern.length, 50, 100);\n * }\n *
\n */\n p5.SoundLoop = function(callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n 'callback' : function(time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);}\n },\n 'frequency' : this._calcFreq()\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function(timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n\n /**\n * Synchronize loops. Use this method to start two more more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function(otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function() {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function() {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return this._bpm / 60 / this._convertNotation(this._interval) * (this._timeSignature / 4);\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function(value) {\n var type = value.slice(-1);\n value = Number(value.slice(0,-1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn('Specified interval is not formatted correctly. See Tone.js '+\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time');\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function(value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function(value) {\n return this._timeSignature / value ;\n };\n\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get : function() {\n return this._bpm;\n },\n set : function(bpm) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the BPM in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._bpm = bpm;\n this._update();\n }\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get : function() {\n return this._timeSignature;\n },\n set : function(timeSig) {\n if (!this.musicalTimeMode) {\n console.warn('Changing the timeSignature in \"seconds\" mode has no effect. '+\n 'BPM is only relevant in musicalTimeMode '+\n 'when the interval is specified as a string '+\n '(\"2n\", \"4n\", \"1m\"...etc)');\n }\n this._timeSignature = timeSig;\n this._update();\n }\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get : function() {\n return this._interval;\n },\n set : function(interval) {\n this.musicalTimeMode = typeof interval === 'Number'? false : true;\n this._interval = interval;\n this._update();\n }\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get : function() {\n return this.clock.ticks;\n }\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n\t'use strict';\n\n\tvar p5sound = require('master');\n\tvar Effect = require('effect');\n var CustomError = require('errorHandler');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n\tp5.Compressor = function() {\n\t\tEffect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n\n\t\tthis.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n\t};\n\n\tp5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n\tp5.Compressor.prototype.process = function(src, attack, knee,\n ratio, threshold, release) {\n\t\tsrc.connect(this.input);\n\t\tthis.set(attack, knee, ratio, threshold, release);\n\t};\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (attack, knee,\n ratio, threshold, release) {\n\n if (typeof attack !== 'undefined') {this.attack(attack);}\n if (typeof knee !== 'undefined') {this.knee(knee);}\n if (typeof ratio !== 'undefined') {this.ratio(ratio);}\n if (typeof threshold !== 'undefined') {this.threshold(threshold);}\n if (typeof release !== 'undefined') {this.release(release);}\n };\n\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time){\n var t = time || 0;\n if (typeof attack == 'number'){\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.attack.linearRampToValueAtTime(attack, this.ac.currentTime + 0.02 + t);\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time){\n var t = time || 0;\n if (typeof knee == 'number'){\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.knee.linearRampToValueAtTime(knee, this.ac.currentTime + 0.02 + t);\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time){\n var t = time || 0;\n if (typeof ratio == 'number'){\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.ratio.linearRampToValueAtTime(ratio, this.ac.currentTime + 0.02 + t);\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time){\n var t = time || 0;\n if (typeof threshold == 'number'){\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.threshold.linearRampToValueAtTime(threshold, this.ac.currentTime + 0.02 + t);\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time){\n var t = time || 0;\n if (typeof release == 'number'){\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.compressor.release.linearRampToValueAtTime(release, this.ac.currentTime + 0.02 + t);\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction =function() {\n return this.compressor.reduction.value;\n };\n\n\n\tp5.Compressor.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n\t};\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n const p5sound = require('master');\n const { convertToWav, safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n const ac = p5sound.audiocontext;\n\n /**\n *

Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().

\n *

The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.

\n *\n * @class p5.SoundRecorder\n * @constructor\n * @example\n *
\n * let mic, recorder, soundFile;\n * let state = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * textAlign(CENTER, CENTER);\n *\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('tap to record', width/2, height/2);\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', width/2, height/2);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Done! Tap to play and download', width/2, height/2, width - 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function() {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n const workletBufferSize = safeBufferSize(1024);\n\n this._workletNode = new AudioWorkletNode(ac, processorNames.recorderProcessor, {\n outputChannelCount: [this._outputChannels],\n processorOptions: {\n numInputChannels: this._inputChannels,\n bufferSize: workletBufferSize\n }\n });\n\n this._workletNode.port.onmessage = function(event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer)\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function() {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function(unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function(sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n }\n else if (sFile) {\n this._callback = function(buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function() {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function() {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *

PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *

\n *

\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *

\n *

\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *

\n *\n *

threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.

\n *\n *

\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *

\n *\n *

\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *

\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n *\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 10;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n *\n * // p5.PeakDetect requires a p5.FFT\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n * }\n *\n * function draw() {\n * background(0);\n * text('click to play/pause', width/2, height/2);\n *\n * // peakDetect accepts an fft post-analysis\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * if ( peakDetect.isDetected ) {\n * ellipseWidth = 50;\n * } else {\n * ellipseWidth *= 0.95;\n * }\n *\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // toggle play/stop when canvas is clicked\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * }\n * }\n *
\n */\n p5.PeakDetect = function(freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function() {};\n };\n\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function(fftObject) {\n var nrg = this.energy = fftObject.getEnergy(this.f1,this.f2)/255;\n if (nrg > this.cutoff && nrg > this.threshold && nrg-this.penergy > 0) {\n\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function(callback, val) {\n var self = this;\n\n self._onPeak = function() {\n callback(self.energy, val);\n };\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * let sound1,sound2;\n * let sound1Gain, sound2Gain, masterGain;\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * // create a 'master' gain to which we will connect both soundfiles\n * masterGain = new p5.Gain();\n * masterGain.connect();\n * sound1.disconnect(); // diconnect from p5 output\n * sound1Gain = new p5.Gain(); // setup a gain node\n * sound1Gain.setInput(sound1); // connect the first sound to its input\n * sound1Gain.connect(masterGain); // connect its output to the 'master'\n * sound2.disconnect();\n * sound2Gain = new p5.Gain();\n * sound2Gain.setInput(sound2);\n * sound2Gain.connect(masterGain);\n * }\n * function startSound() {\n * sound1.loop();\n * sound2.loop();\n * loop();\n * }\n * function mouseReleased() {\n * sound1.stop();\n * sound2.stop();\n * }\n * function draw(){\n * background(220);\n * textAlign(CENTER);\n * textSize(11);\n * fill(0);\n * if (!sound1.isPlaying()) {\n * text('tap and drag to play', width/2, height/2);\n * return;\n * }\n * // map the horizontal position of the mouse to values useable for volume * control of sound1\n * var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n * var sound2Volume = 1-sound1Volume;\n * sound1Gain.amp(sound1Volume);\n * sound2Gain.amp(sound2Volume);\n * // map the vertical position of the mouse to values useable for 'master * volume control'\n * var masterVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n * masterGain.amp(masterVolume);\n * text('master', width/2, height - masterVolume * height * 0.9)\n * fill(255, 0, 255);\n * textAlign(LEFT);\n * text('sound1', 5, height - sound1Volume * height * 0.9);\n * textAlign(RIGHT);\n * text('sound2', width - 5, height - sound2Volume * height * 0.9);\n * }\n *
\n */\n\n p5.Gain = function() {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n\n p5.Gain.prototype.setInput = function(src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function(unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function() {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function(vol, rampTime, tFromNow) {\n var rampTime = rampTime || 0;\n var tFromNow = tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function() {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n\n});\n","'use strict';\n\ndefine(function (require) {\n\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for ( ; i < numSamples; ++i ) {\n x = i * 2 / numSamples - 1;\n curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function(amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n } if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n } if (typeof oversample === 'undefined') {\n oversample = '2x';\n } if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function(src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function(amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function() {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function() {\n return this.waveShaperNode.oversample;\n };\n\n\n p5.Distortion.prototype.dispose = function() {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///../node_modules/tone/Tone/core/Tone.js","webpack:///./master.js","webpack:///../node_modules/tone/Tone/signal/Signal.js","webpack:///../node_modules/tone/Tone/signal/Multiply.js","webpack:///../node_modules/tone/Tone/signal/WaveShaper.js","webpack:///./effect.js","webpack:///./helpers.js","webpack:///../node_modules/tone/Tone/signal/Add.js","webpack:///../node_modules/tone/Tone/type/Type.js","webpack:///../node_modules/tone/Tone/core/Gain.js","webpack:///./audioWorklet/processorNames.js","webpack:///../node_modules/tone/Tone/core/Context.js","webpack:///./errorHandler.js","webpack:///../node_modules/tone/Tone/signal/Scale.js","webpack:///../node_modules/tone/Tone/signal/TimelineSignal.js","webpack:///./filter.js","webpack:///../node_modules/tone/Tone/signal/Subtract.js","webpack:///./audiocontext.js","webpack:///../node_modules/tone/Tone/core/Emitter.js","webpack:///../node_modules/tone/Tone/signal/SignalBase.js","webpack:///../node_modules/tone/Tone/type/Time.js","webpack:///../node_modules/tone/Tone/type/TimeBase.js","webpack:///../node_modules/tone/Tone/core/Param.js","webpack:///./oscillator.js","webpack:///../node_modules/tone/Tone/core/Timeline.js","webpack:///../node_modules/tone/Tone/signal/Negate.js","webpack:///../node_modules/tone/Tone/signal/GreaterThanZero.js","webpack:///../node_modules/tone/Tone/core/Clock.js","webpack:///./monosynth.js","webpack:///./audioVoice.js","webpack:///./polysynth.js","webpack:///./app.js","webpack:///../node_modules/audioworklet-polyfill/dist/audioworklet-polyfill.js","webpack:///./shims.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/startaudiocontext/StartAudioContext.js","webpack:///./audioWorklet/index.js","webpack:///./audioWorklet/recorderProcessor.js","webpack:///./audioWorklet/soundFileProcessor.js","webpack:///./audioWorklet/amplitudeProcessor.js","webpack:///./panner.js","webpack:///./soundfile.js","webpack:///./amplitude.js","webpack:///./fft.js","webpack:///./signal.js","webpack:///../node_modules/tone/Tone/type/Frequency.js","webpack:///../node_modules/tone/Tone/type/TransportTime.js","webpack:///./envelope.js","webpack:///./pulse.js","webpack:///./noise.js","webpack:///./audioin.js","webpack:///../node_modules/tone/Tone/component/CrossFade.js","webpack:///../node_modules/tone/Tone/signal/Expr.js","webpack:///../node_modules/tone/Tone/signal/GreaterThan.js","webpack:///../node_modules/tone/Tone/signal/Abs.js","webpack:///../node_modules/tone/Tone/signal/Modulo.js","webpack:///../node_modules/tone/Tone/signal/Pow.js","webpack:///../node_modules/tone/Tone/signal/AudioToGain.js","webpack:///../node_modules/tone/Tone/signal/EqualPowerGain.js","webpack:///./eq.js","webpack:///./eqFilter.js","webpack:///./panner3d.js","webpack:///./listener3d.js","webpack:///./delay.js","webpack:///./reverb.js","webpack:///./metro.js","webpack:///../node_modules/tone/Tone/core/TimelineState.js","webpack:///./looper.js","webpack:///./soundLoop.js","webpack:///./compressor.js","webpack:///./soundRecorder.js","webpack:///./peakDetect.js","webpack:///./gain.js","webpack:///./distortion.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","define","Tone","inputs","outputs","this","isUndef","input","context","createGain","Array","output","audioContext","set","params","rampTime","isObject","isString","tmpObj","paramLoop","attr","parent","indexOf","attrSplit","split","length","splice","innerParam","join","param","Signal","Param","rampTo","AudioParam","_collectDefaults","constructor","ret","subRet","j","subAttr","isFunction","constr","defaults","keys","_super","superDefs","push","toString","className","isLetter","match","sameConstructor","isArray","dispose","AudioNode","disconnect","connect","unit","outputNum","inputNum","defaultArg","destination","isNumber","apply","arguments","connectSeries","currentUnit","toUnit","chain","fan","given","fallback","givenProp","fallbackProp","optionsObject","values","options","val","arg","isBoolean","noOp","_readOnly","writable","_writable","State","Started","Stopped","Paused","equalPowerScale","percent","piFactor","Math","PI","sin","dbToGain","db","pow","gainToDb","gain","log","LN10","intervalToFrequencyRatio","interval","now","extend","child","TempConstructor","Context","emit","setContext","ctx","sampleRate","hasAudioContext","window","hasPromises","hasWorkers","version","TONE_SILENCE_VERSION_LOGGING","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","undefined","audiocontext","p5sound","limiter","createDynamicsCompressor","threshold","ratio","knee","meter","fftMeter","soundArray","parts","extensions","p5","getMasterVolume","masterVolume","vol","tFromNow","currentTime","currentVol","cancelScheduledValues","linearRampToValueAtTime","soundOut","_silentNode","_gain","_param","getConstant","units","Type","Default","convert","SignalBase","Multiply","createInsOuts","_mult","Gain","WaveShaper","mapping","bufferLen","_shaper","createWaveShaper","_curve","curve","isFinite","Float32Array","setMap","len","normalized","oversample","oversampling","RangeError","require","CrossFade","Effect","ac","_drywet","wet","a","b","amp","startTime","endTime","drywet","fade","u","index","processorNames","freqToMidi","f","mathlog2","round","midiToFreq","writeUTFBytes","view","offset","string","lng","setUint8","charCodeAt","soundFormats","toLowerCase","disposeSound","registerMethod","_checkFileFormats","paths","path","extTest","pop","isFileSupported","pathSplit","pathCore","extension","_typeof","_mathChain","math","thisChain","nextChain","type","mathOps","convertToWav","audioBuffer","leftChannel","interleaved","rightChannel","result","inputIndex","interleave","getChannelData","numberOfChannels","buffer","ArrayBuffer","DataView","setUint32","setUint16","setInt16","noteToFreq","note","A","B","C","D","E","F","G","toUpperCase","slice","safeBufferSize","idealBufferSize","bufferSize","tempAudioWorkletNode","AudioWorkletNode","soundFileProcessor","ScriptProcessorNode","Add","_sum","Time","Frequency","TransportTime","Ticks","NormalRange","AudioRange","Decibels","Interval","BPM","Positive","Cents","Degrees","MIDI","BarsBeatsSixteenths","Samples","Hertz","Note","Milliseconds","Seconds","Notation","toSeconds","time","TimeBase","toFrequency","freq","valueOf","toTicks","Transport","ticks","GainNode","AudioContext","createGainNode","_gainNode","recorderProcessor","amplitudeProcessor","toneConnect","outNum","inNum","nativeConnect","e","Error","nativeDisconnect","webkitAudioContext","prop","Emitter","_context","_defineProperty","_latencyHint","_lookAhead","_updateInterval","_computedUpdateInterval","_worker","_createWorker","_constants","mixin","URL","webkitURL","blob","Blob","toFixed","blobUrl","createObjectURL","worker","Worker","addEventListener","_lastUpdate","diff","max","createBuffer","arr","constant","createBufferSource","channelCount","channelCountMode","loop","start","lA","blockTime","postMessage","hint","lookAhead","latencyHint","updateInterval","supported","errorTrace","failedPath","tempStack","splitStack","err","originalStack","stack","filter","ln","Scale","outputMin","outputMax","_outputMin","_outputMax","_scale","_add","_setRange","min","TimelineSignal","_events","Timeline","_initial","_fromUnits","Linear","Exponential","Target","Curve","Set","getValueAtTime","_toUnits","convertedVal","setValueAtTime","add","exponentialRampToValueAtTime","beforeEvent","_searchBefore","_minOutput","setValue","sampleTime","setTargetAtTime","timeConstant","setValueCurveAtTime","duration","scaling","floats","segmentTime","after","cancel","setRampPoint","before","_searchAfter","linearRampToValueBetween","finish","exponentialRampToValueBetween","getAfter","previouVal","previous","getBefore","_exponentialApproach","_curveInterpolate","_linearInterpolate","_exponentialInterpolate","t0","v0","v1","exp","t1","progress","lowerIndex","floor","upperIndex","ceil","lowerVal","upperVal","Filter","biquad","createBiquadFilter","setType","_on","_untoggledType","process","src","res","frequency","Q","toggle","LowPass","HighPass","BandPass","Subtract","_neg","Negate","global","StartAudioContext","getAudioContext","userStartAudio","elements","callback","elt","Element","map","on","event","events","eventName","off","ev","eventList","args","functions","func","emitterFunc","node","outputNumber","inputNumber","overridden","_plusNow","_unaryExpressions","quantize","regexp","method","rh","nextSubdivision","lh","subdiv","_expr","expr","subdivision","addNow","_defaultExpr","_noOp","copy","toNotation","retNotation","_toNotationHelper","retTripletNotation","testNotations","_notationToUnits","notationTime","multiple","notation","primaryExprs","_primaryExpressions","notationExprs","toBarsBeatsSixteenths","quarterTime","_beatsToUnits","quarters","measures","_timeSignature","sixteenths","parseFloat","PPQ","toSamples","toMilliseconds","_defaultUnits","exprString","_parseExprString","clone","instance","parseInt","_ticksToUnits","hz","_frequencyToUnits","tr","q","total","_secondsToUnits","samples","default","_binaryExpressions","+","precedence","-","*","/","neg","_syntaxGlue","(",")","_tokenize","position","tokens","token","getNextToken","trim","substr","expressions","group","opName","op","reg","SyntaxError","next","peek","_matchGroup","prec","test","_parseBinary","lexer","_parseUnary","_parsePrimary","matching","beats","bpm","seconds","timeSignature","_pushExpr","sub","mult","div","_lfo","lfo","LFO","currentVal","exponentialRampToValue","linearRampToValue","Mult","Oscillator","started","phaseAmount","oscillator","createOscillator","_freqMods","panPosition","connection","panner","Panner","stop","abs","freqNode","getAmp","isNaN","phase","getFreq","getType","oscMods","pan","pval","getPan","osc2","delayAmt","dNode","createDelay","delayTime","sigChain","mathObj","chainSource","num","scale","inMin","inMax","outMin","outMax","mapOutMin","mapOutMax","SinOsc","TriOsc","SawOsc","SqrOsc","_timeline","_toRemove","_iterating","memory","Infinity","_search","remove","shift","cancelBefore","beginning","end","midPoint","nextEvent","_iterate","lowerBound","upperBound","forEach","forEachBefore","forEachAfter","forEachFrom","forEachAtTime","_multiply","GreaterThanZero","_thresh","Clock","_nextTick","_lastState","_state","TimelineState","_boundLoop","_loop","state","setStateAtTime","pause","loopInterval","lag","currentState","tickTime","getStateAtTime","AudioVoice","MonoSynth","env","Envelope","setRange","setExp","setADSR","setInput","play","velocity","secondsFromNow","susTime","triggerAttack","triggerRelease","vel","ramp","attack","decay","sustain","release","defineProperties","aTime","dTime","sPercent","rTime","sustime","PolySynth","audioVoice","maxVoices","audiovoices","notes","_newest","_oldest","_voicesInUse","_allocateVoices","noteAttack","noteRelease","noteADSR","timeFromNow","voice","_note","_velocity","currentVoice","acTime","oldestNote","previousVal","_updateAfter","maxRange","nextTime","p5SOUND","parameters","fill","processor","realm","exec","inputBuffer","outputBuffer","$$processors","$$context","self","createScriptProcessor","outputChannelCount","Map","properties","defaultValue","MessageChannel","port2","Processor","port","port1","onaudioprocess","$$audioWorklet","AudioWorklet","addModule","fetch","then","ok","status","text","AudioWorkletProcessor","registerProcessor","parameterDescriptors","document","createElement","style","cssText","appendChild","contentWindow","createTextNode","body","$hook","console","documentElement","transpile","String","fixSetTarget","setTargetValueAtTime","createDelayNode","createJavaScriptNode","createPeriodicWave","createWaveTable","internal_createGain","internal_createDelay","maxDelayTime","internal_createBufferSource","internal_start","when","noteGrainOn","noteOn","internal_stop","noteOff","playbackRate","internal_createDynamicsCompressor","reduction","internal_createBiquadFilter","detune","internal_createOscillator","setPeriodicWave","setWaveTable","OfflineAudioContext","webkitOfflineAudioContext","navigator","getUserMedia","webkitGetUserMedia","mozGetUserMedia","msGetUserMedia","el","isSupported","canPlayType","g","Function","factory","__WEBPACK_AMD_DEFINE_FACTORY__","TapListener","element","_dragged","_element","_bindedMove","_moved","_bindedEnd","_ended","isStarted","source","resume","removeEventListener","promise","Promise","success","checkLoop","requestAnimationFrame","tapListeners","bindTapListener","NodeList","querySelectorAll","jquery","toArray","tap","moduleSources","initializedAudioWorklets","preload","_incrementPreload","onWorkletModulesLoad","_decrementPreload","all","moduleSrc","objectURL","audioWorklet","__webpack_exports__","createStereoPanner","stereoPanner","inputChannels","obj","numInputChannels","left","right","channelInterpretation","splitter","createChannelSplitter","createChannelMerger","v","rightVal","cos","leftVal","numChannels","CustomError","_require","SoundFile","onload","onerror","whileLoading","url","File","FileReader","FileList","file","_onended","_looping","_playing","_paused","_pauseTime","_cues","_cueIDCounter","_lastPos","_counterNode","_workletNode","bufferSourceNodes","bufferSourceNode","reversed","pauseTime","startMillis","load","_whileLoading","_clearOnEnd","thisBufferSourceNode","target","soundFile","_","reverse","registerPreloadMethod","loadSound","location","origin","cordova","alert","errorCallback","request","XMLHttpRequest","evt","_updateProgress","open","responseType","decodeAudioData","response","buff","msg","statusText","message","send","reader","readAsArrayBuffer","lengthComputable","percentComplete","loaded","isLoaded","rate","_cueStart","cueStart","cueEnd","setVolume","isPlaying","_initSourceNode","_initCounterNode","_arrayIndex","loopStart","loopEnd","playMode","str","pTime","setLoop","bool","isLooping","isPaused","stopAll","_time","_rampTime","_tFromNow","getVolume","reverseBuffer","setPitch","newPlaybackRate","getPlaybackRate","jump","cueTime","cTime","dur","channels","frames","getPeaks","width","sampleSize","sampleStep","peaks","chan","currentPos","curVol","onended","getLevel","setPath","setBuffer","buf","size","newBuffer","channelNum","_this","cNode","workletBufferSize","processorOptions","onmessage","data","_onTimeUpdate","audioBuf","arrayBuffer","_createCounterBuffer","processPeaks","_initThreshold","_minThreshold","_minPeaks","bufLen","allPeaks","minThreshold","minPeaks","offlineContext","startRendering","oncomplete","filteredBuffer","renderedBuffer","bufferData","getPeaksAtThreshold","topTempos","intervalCounts","tempoCounts","intervalCount","theoreticalTempo","mapTempo","some","tempoCount","tempo","count","groupNeighborsByTempo","peaksObj","peaksArray","sort","startPeak","endPeak","startPos","sampleIndex","intervals","countIntervalsBetweenNearbyPeaks","intA","intB","tempoPeaks","bpmVariance","peaksAtTopTempo","peak","intervalBPM","peakTime","getPeaksAtTopTempo","Peak","amplitude","tempos","Cue","id","addCue","cue","removeCue","cueLength","clearCues","playbackTime","callbackTime","_prevUpdateTime","save","fileName","saveSound","getBlob","dataView","Amplitude","smoothing","parameterData","normalize","volume","volNorm","stereoVol","stereoVolNorm","channel","toggleNormalize","smooth","FFT","bins","analyser","createAnalyser","fftSize","configurable","smoothingTimeConstant","freqDomain","Uint8Array","frequencyBinCount","timeDomain","bass","lowMid","mid","highMid","treble","waveform","normalArray","_isSafari","fft","timeToFloat","getFloatTimeDomainData","timeToInt","getByteTimeDomainData","scaled","analyze","freqToFloat","getFloatFrequencyData","freqToInt","getByteFrequencyData","getEnergy","frequency1","frequency2","nyquist","swap","lowIndex","highIndex","numFrequencies","freq1","freq2","getCentroid","cumulative_sum","centroid_normalization","mean_freq_index","linAverages","_N","N","spectrum","spectrumLength","spectrumStep","linearAverages","groupIndex","specIndex","logAverages","octaveBands","octaveIndex","hi","getOctaveBands","_fCtr0","fCtr0","lastFrequencyBand","lo","ctr","newFrequencyBand","_input","midi","midiToFrequency","pitch","octave","noteNumber","noteToScaleIndex","transpose","harmonize","toMidi","frequencyToMidi","toNote","A4","LN2","scaleIndexToNote","cbb","cb","c#","cx","dbb","d#","dx","ebb","eb","e#","ex","fbb","fb","f#","fx","gbb","gb","g#","gx","abb","ab","a#","ax","bbb","bb","b#","bx","_secondsToTicks","l1","t2","l2","t3","l3","aLevel","dLevel","rLevel","_rampHighPercentage","_rampLowPercentage","control","_init","isExponential","sourceToClear","wasTriggered","_setRampAD","_rampAttackTime","checkExpInput","_rampDecayTime","TCDenominator","_rampAttackTC","_rampDecayTC","setRampPercentages","p1","p2","isExp","lastAttack","valToSet","v2","destination1","destination2","AudioIn","Reverb","Noise","Delay","Env","createDCOffset","bufferSource","Pulse","w","dcOffset","dcGain","mW","sig","SignalAdd","mods","currentFreq","freqMod","_whiteNoiseBuffer","whiteBuffer","noiseData","random","_pinkNoiseBuffer","b0","b1","b2","b3","b4","b5","b6","pinkBuffer","white","_brownNoiseBuffer","brownBuffer","lastOut","assignType","noise","inputSources","stream","mediaStream","currentSource","enabled","MediaStreamTrack","mediaDevices","successCallback","audioSource","constraints","audio","echoCancellation","deviceId","createMediaStreamSource","getTracks","track","getSources","onSuccess","onError","resolve","reject","enumerateDevices","devices","device","kind","error","setSource","active","initialFade","_equalPowerA","EqualPowerGain","_equalPowerB","_invert","Expr","applyBinary","Constructor","_eval","applyUnary","getNumber","literalNumber","_replacements","inputCount","_parseInputs","_nodes","tree","_parseTree","_disposeNodes","_Expressions","signal","glue",",","Abs","mod","modulus","Modulo","Pow","a2g","AudioToGain","binary","unary","!","NOT","inputArray","inputMax","replace","matchSyntax","syn","matchGroup","groupName","parseExpression","parseUnary","operator","parsePrimary","GreaterThan","_gtz","_abs","_subtract","_modSignal","_setWaveShaper","_exp","_expScaler","_expFunc","_norm","x","_eqPower","EQFilter","EQ","_eqsize","factor","bands","_newBand","Panner3D","createPanner","panningModel","distanceModel","xVal","yVal","zVal","positionX","positionY","positionZ","orient","orientX","orientY","orientZ","orientationX","orientationY","orientationZ","setFalloff","maxDistance","rolloffFactor","maxDist","rolloff","Listener3D","listener","xValF","yValF","zValF","xValU","yValU","zValU","orientForward","orientUp","forwardX","forwardY","forwardZ","upX","upY","upZ","_split","_merge","_leftGain","_rightGain","leftDelay","rightDelay","_leftFilter","_rightFilter","_maxDelay","maxValue","feedback","_delayTime","_feedback","_filter","_initConvolverNode","_seconds","_decay","_reverse","_buildImpulse","convolverNode","createConvolver","_teardownConvolverNode","_setBuffer","decayRate","rebuild","impulse","impulseL","impulseR","Convolver","impulses","_loadBuffer","cReverb","_path","chunks","addImpulse","resetImpulse","toggleImpulse","Metro","clock","ontick","syncedParts","prevTick","tatumTime","tickCallback","elapsedTime","thisPart","incrementStep","phrases","thisPhrase","phraseArray","sequence","bNum","metroTicks","looping","setBPM","beatTime","tatums","getBPM","getRate","resetSync","part","pushSync","beatLength","initial","playNextPart","aScore","currentPart","scoreStep","Phrase","phraseStep","Part","steps","bLength","partStep","noLoop","metro","addPhrase","array","removePhrase","getPhrase","replaceSequence","onStep","Score","thisScore","nextPart","resetPart","resetParts","SoundLoop","musicalTimeMode","_interval","_bpm","maxIterations","iterations","_calcFreq","syncedStart","otherLoop","_update","_convertNotation","Number","_measure","timeSig","Compressor","compressor","number","SoundRecorder","_inputChannels","_outputChannels","buffers","leftBuffer","rightBuffer","_callback","record","sFile","writeFile","PeakDetect","_framesPerPeak","framesPerPeak","framesSinceLastPeak","cutoff","cutoffMult","energy","penergy","currentValue","isDetected","f1","f2","_onPeak","update","fftObject","nrg","onPeak","makeDistortionCurve","amount","k","deg","Distortion","curveAmount","waveShaperNode","getAmount","getOversample"],"mappings":"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","file":"p5.sound.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 31);\n","/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2017 Yotam Mann\n */\ndefine(function(){\n\n\t\"use strict\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTONE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * @class Tone is the base class of all other classes. It provides \n\t * a lot of methods and functionality to all classes that extend\n\t * it. \n\t * \n\t * @constructor\n\t * @alias Tone\n\t * @param {number} [inputs=1] the number of input nodes\n\t * @param {number} [outputs=1] the number of output nodes\n\t */\n\tvar Tone = function(inputs, outputs){\n\n\t\t/**\n\t\t * the input node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(inputs) || inputs === 1){\n\t\t\tthis.input = this.context.createGain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\t/**\n\t\t * the output node(s)\n\t\t * @type {GainNode|Array}\n\t\t */\n\t\tif (this.isUndef(outputs) || outputs === 1){\n\t\t\tthis.output = this.context.createGain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t/**\n\t * Set the parameters at once. Either pass in an\n\t * object mapping parameters to values, or to set a\n\t * single parameter, by passing in a string and value.\n\t * The last argument is an optional ramp time which \n\t * will ramp any signal values to their destination value\n\t * over the duration of the rampTime.\n\t * @param {Object|string} params\n\t * @param {number=} value\n\t * @param {Time=} rampTime\n\t * @returns {Tone} this\n\t * @example\n\t * //set values using an object\n\t * filter.set({\n\t * \t\"frequency\" : 300,\n\t * \t\"type\" : highpass\n\t * });\n\t * @example\n\t * filter.set(\"type\", \"highpass\");\n\t * @example\n\t * //ramp to the value 220 over 3 seconds. \n\t * oscillator.set({\n\t * \t\"frequency\" : 220\n\t * }, 3);\n\t */\n\tTone.prototype.set = function(params, value, rampTime){\n\t\tif (this.isObject(params)){\n\t\t\trampTime = value;\n\t\t} else if (this.isString(params)){\n\t\t\tvar tmpObj = {};\n\t\t\ttmpObj[params] = value;\n\t\t\tparams = tmpObj;\n\t\t}\n\n\t\tparamLoop:\n\t\tfor (var attr in params){\n\t\t\tvalue = params[attr];\n\t\t\tvar parent = this;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var i = 0; i < attrSplit.length - 1; i++){\n\t\t\t\t\tparent = parent[attrSplit[i]];\n\t\t\t\t\tif (parent instanceof Tone) {\n\t\t\t\t\t\tattrSplit.splice(0,i+1);\n\t\t\t\t\t\tvar innerParam = attrSplit.join(\".\");\n\t\t\t\t\t\tparent.set(innerParam, value);\n\t\t\t\t\t\tcontinue paramLoop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isUndef(param)){\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif ((Tone.Signal && param instanceof Tone.Signal) || \n\t\t\t\t\t(Tone.Param && param instanceof Tone.Param)){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tif (this.isUndef(rampTime)){\n\t\t\t\t\t\tparam.value = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparam.rampTo(value, rampTime);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tif (param.value !== value){\n\t\t\t\t\tparam.value = value;\n\t\t\t\t}\t\t\t\t\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tparam.set(value);\n\t\t\t} else if (param !== value){\n\t\t\t\tparent[attr] = value;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the object's attributes. Given no arguments get\n\t * will return all available object properties and their corresponding\n\t * values. Pass in a single attribute to retrieve or an array\n\t * of attributes. The attribute strings can also include a \".\"\n\t * to access deeper properties.\n\t * @example\n\t * osc.get();\n\t * //returns {\"type\" : \"sine\", \"frequency\" : 440, ...etc}\n\t * @example\n\t * osc.get(\"type\");\n\t * //returns { \"type\" : \"sine\"}\n\t * @example\n\t * //use dot notation to access deep properties\n\t * synth.get([\"envelope.attack\", \"envelope.release\"]);\n\t * //returns {\"envelope\" : {\"attack\" : 0.2, \"release\" : 0.4}}\n\t * @param {Array=|string|undefined} params the parameters to get, otherwise will return \n\t * \t\t\t\t\t all available.\n\t * @returns {Object}\n\t */\n\tTone.prototype.get = function(params){\n\t\tif (this.isUndef(params)){\n\t\t\tparams = this._collectDefaults(this.constructor);\n\t\t} else if (this.isString(params)){\n\t\t\tparams = [params];\n\t\t} \n\t\tvar ret = {};\n\t\tfor (var i = 0; i < params.length; i++){\n\t\t\tvar attr = params[i];\n\t\t\tvar parent = this;\n\t\t\tvar subRet = ret;\n\t\t\tif (attr.indexOf(\".\") !== -1){\n\t\t\t\tvar attrSplit = attr.split(\".\");\n\t\t\t\tfor (var j = 0; j < attrSplit.length - 1; j++){\n\t\t\t\t\tvar subAttr = attrSplit[j];\n\t\t\t\t\tsubRet[subAttr] = subRet[subAttr] || {};\n\t\t\t\t\tsubRet = subRet[subAttr];\n\t\t\t\t\tparent = parent[subAttr];\n\t\t\t\t}\n\t\t\t\tattr = attrSplit[attrSplit.length - 1];\n\t\t\t}\n\t\t\tvar param = parent[attr];\n\t\t\tif (this.isObject(params[attr])){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (Tone.Signal && param instanceof Tone.Signal){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (Tone.Param && param instanceof Tone.Param){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof AudioParam){\n\t\t\t\tsubRet[attr] = param.value;\n\t\t\t} else if (param instanceof Tone){\n\t\t\t\tsubRet[attr] = param.get();\n\t\t\t} else if (!this.isFunction(param) && !this.isUndef(param)){\n\t\t\t\tsubRet[attr] = param;\n\t\t\t} \n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * collect all of the default attributes in one\n\t * @private\n\t * @param {function} constr the constructor to find the defaults from\n\t * @return {Array} all of the attributes which belong to the class\n\t */\n\tTone.prototype._collectDefaults = function(constr){\n\t\tvar ret = [];\n\t\tif (!this.isUndef(constr.defaults)){\n\t\t\tret = Object.keys(constr.defaults);\n\t\t}\n\t\tif (!this.isUndef(constr._super)){\n\t\t\tvar superDefs = this._collectDefaults(constr._super);\n\t\t\t//filter out repeats\n\t\t\tfor (var i = 0; i < superDefs.length; i++){\n\t\t\t\tif (ret.indexOf(superDefs[i]) === -1){\n\t\t\t\t\tret.push(superDefs[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * @returns {string} returns the name of the class as a string\n\t */\n\tTone.prototype.toString = function(){\n\t\tfor (var className in Tone){\n\t\t\tvar isLetter = className[0].match(/^[A-Z]$/);\n\t\t\tvar sameConstructor = Tone[className] === this.constructor;\n\t\t\tif (this.isFunction(Tone[className]) && isLetter && sameConstructor){\n\t\t\t\treturn className;\n\t\t\t}\n\t\t}\n\t\treturn \"Tone\";\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCLASS VARS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The number of inputs feeding into the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfInputs\", {\n\t\tget : function(){\n\t\t\tif (this.input){\n\t\t\t\tif (this.isArray(this.input)){\n\t\t\t\t\treturn this.input.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The number of outputs coming out of the AudioNode. \n\t * For source nodes, this will be 0.\n\t * @memberOf Tone#\n\t * @name numberOfInputs\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"numberOfOutputs\", {\n\t\tget : function(){\n\t\t\tif (this.output){\n\t\t\t\tif (this.isArray(this.output)){\n\t\t\t\t\treturn this.output.length;\n\t\t\t\t} else {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\t\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONNECTIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * disconnect and dispose\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.dispose = function(){\n\t\tif (!this.isUndef(this.input)){\n\t\t\tif (this.input instanceof AudioNode){\n\t\t\t\tthis.input.disconnect();\n\t\t\t} \n\t\t\tthis.input = null;\n\t\t}\n\t\tif (!this.isUndef(this.output)){\n\t\t\tif (this.output instanceof AudioNode){\n\t\t\t\tthis.output.disconnect();\n\t\t\t} \n\t\t\tthis.output = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode\n\t * @param {Tone | AudioParam | AudioNode} unit \n\t * @param {number} [outputNum=0] optionally which output to connect from\n\t * @param {number} [inputNum=0] optionally which input to connect to\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connect = function(unit, outputNum, inputNum){\n\t\tif (Array.isArray(this.output)){\n\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\tthis.output[outputNum].connect(unit, 0, inputNum);\n\t\t} else {\n\t\t\tthis.output.connect(unit, outputNum, inputNum);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * disconnect the output\n\t * @param {Number|AudioNode} output Either the output index to disconnect\n\t * if the output is an array, or the\n\t * node to disconnect from.\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.disconnect = function(destination, outputNum, inputNum){\n\t\tif (this.isArray(this.output)){\n\t\t\tif (this.isNumber(destination)){\n\t\t\t\tthis.output[destination].disconnect();\n\t\t\t} else {\n\t\t\t\toutputNum = this.defaultArg(outputNum, 0);\n\t\t\t\tthis.output[outputNum].disconnect(destination, 0, inputNum);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.output.disconnect.apply(this.output, arguments);\n\t\t}\n\t};\n\n\t/**\n\t * connect together all of the arguments in series\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.connectSeries = function(){\n\t\tif (arguments.length > 1){\n\t\t\tvar currentUnit = arguments[0];\n\t\t\tfor (var i = 1; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Connect the output of this node to the rest of the nodes in series.\n\t * @example\n\t * //connect a node to an effect, panVol and then to the master output\n\t * node.chain(effect, panVol, Tone.Master);\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.chain = function(){\n\t\tif (arguments.length > 0){\n\t\t\tvar currentUnit = this;\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tvar toUnit = arguments[i];\n\t\t\t\tcurrentUnit.connect(toUnit);\n\t\t\t\tcurrentUnit = toUnit;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * connect the output of this node to the rest of the nodes in parallel.\n\t * @param {...AudioParam|Tone|AudioNode} nodes\n\t * @returns {Tone} this\n\t */\n\tTone.prototype.fan = function(){\n\t\tif (arguments.length > 0){\n\t\t\tfor (var i = 0; i < arguments.length; i++){\n\t\t\t\tthis.connect(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t//give native nodes chain and fan methods\n\tAudioNode.prototype.chain = Tone.prototype.chain;\n\tAudioNode.prototype.fan = Tone.prototype.fan;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUTILITIES / HELPERS / MATHS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * If the `given` parameter is undefined, use the `fallback`. \n\t * If both `given` and `fallback` are object literals, it will\n\t * return a deep copy which includes all of the parameters from both \n\t * objects. If a parameter is undefined in given, it will return\n\t * the fallback property. \n\t *

\n\t * WARNING: if object is self referential, it will go into an an \n\t * infinite recursive loop.\n\t * \n\t * @param {*} given \n\t * @param {*} fallback \n\t * @return {*} \n\t */\n\tTone.prototype.defaultArg = function(given, fallback){\n\t\tif (this.isObject(given) && this.isObject(fallback)){\n\t\t\tvar ret = {};\n\t\t\t//make a deep copy of the given object\n\t\t\tfor (var givenProp in given) {\n\t\t\t\tret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]);\n\t\t\t}\n\t\t\tfor (var fallbackProp in fallback) {\n\t\t\t\tret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn this.isUndef(given) ? fallback : given;\n\t\t}\n\t};\n\n\t/**\n\t * returns the args as an options object with given arguments\n\t * mapped to the names provided. \n\t *\n\t * if the args given is an array containing only one object, it is assumed\n\t * that that's already the options object and will just return it. \n\t * \n\t * @param {Array} values the 'arguments' object of the function\n\t * @param {Array} keys the names of the arguments as they\n\t * should appear in the options object\n\t * @param {Object=} defaults optional defaults to mixin to the returned \n\t * options object \n\t * @return {Object} the options object with the names mapped to the arguments\n\t */\n\tTone.prototype.optionsObject = function(values, keys, defaults){\n\t\tvar options = {};\n\t\tif (values.length === 1 && this.isObject(values[0])){\n\t\t\toptions = values[0];\n\t\t} else {\n\t\t\tfor (var i = 0; i < keys.length; i++){\n\t\t\t\toptions[keys[i]] = values[i];\n\t\t\t}\n\t\t}\n\t\tif (!this.isUndef(defaults)){\n\t\t\treturn this.defaultArg(options, defaults);\n\t\t} else {\n\t\t\treturn options;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// TYPE CHECKING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * test if the arg is undefined\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is undefined\n\t * @function\n\t */\n\tTone.prototype.isUndef = function(val){\n\t\treturn typeof val === \"undefined\";\n\t};\n\n\t/**\n\t * test if the arg is a function\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a function\n\t * @function\n\t */\n\tTone.prototype.isFunction = function(val){\n\t\treturn typeof val === \"function\";\n\t};\n\n\t/**\n\t * Test if the argument is a number.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a number\n\t */\n\tTone.prototype.isNumber = function(arg){\n\t\treturn (typeof arg === \"number\");\n\t};\n\n\t/**\n\t * Test if the given argument is an object literal (i.e. `{}`);\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an object literal.\n\t */\n\tTone.prototype.isObject = function(arg){\n\t\treturn (Object.prototype.toString.call(arg) === \"[object Object]\" && arg.constructor === Object);\n\t};\n\n\t/**\n\t * Test if the argument is a boolean.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a boolean\n\t */\n\tTone.prototype.isBoolean = function(arg){\n\t\treturn (typeof arg === \"boolean\");\n\t};\n\n\t/**\n\t * Test if the argument is an Array\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is an array\n\t */\n\tTone.prototype.isArray = function(arg){\n\t\treturn (Array.isArray(arg));\n\t};\n\n\t/**\n\t * Test if the argument is a string.\n\t * @param {*} arg the argument to test\n\t * @returns {boolean} true if the arg is a string\n\t */\n\tTone.prototype.isString = function(arg){\n\t\treturn (typeof arg === \"string\");\n\t};\n\n \t/**\n\t * An empty function.\n\t * @static\n\t */\n\tTone.noOp = function(){};\n\n\t/**\n\t * Make the property not writable. Internal use only. \n\t * @private\n\t * @param {string} property the property to make not writable\n\t */\n\tTone.prototype._readOnly = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._readOnly(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: false,\n\t\t\t\tenumerable : true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Make an attribute writeable. Interal use only. \n\t * @private\n\t * @param {string} property the property to make writable\n\t */\n\tTone.prototype._writable = function(property){\n\t\tif (Array.isArray(property)){\n\t\t\tfor (var i = 0; i < property.length; i++){\n\t\t\t\tthis._writable(property[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tObject.defineProperty(this, property, { \n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * Possible play states. \n\t * @enum {string}\n\t */\n\tTone.State = {\n\t\tStarted : \"started\",\n\t\tStopped : \"stopped\",\n\t\tPaused : \"paused\",\n \t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Equal power gain scale. Good for cross-fading.\n\t * @param {NormalRange} percent (0-1)\n\t * @return {Number} output gain (0-1)\n\t */\n\tTone.prototype.equalPowerScale = function(percent){\n\t\tvar piFactor = 0.5 * Math.PI;\n\t\treturn Math.sin(percent * piFactor);\n\t};\n\n\t/**\n\t * Convert decibels into gain.\n\t * @param {Decibels} db\n\t * @return {Number} \n\t */\n\tTone.prototype.dbToGain = function(db) {\n\t\treturn Math.pow(2, db / 6);\n\t};\n\n\t/**\n\t * Convert gain to decibels.\n\t * @param {Number} gain (0-1)\n\t * @return {Decibels} \n\t */\n\tTone.prototype.gainToDb = function(gain) {\n\t\treturn 20 * (Math.log(gain) / Math.LN10);\n\t};\n\n\t/**\n\t * Convert an interval (in semitones) to a frequency ratio.\n\t * @param {Interval} interval the number of semitones above the base note\n\t * @return {number} the frequency ratio\n\t * @example\n\t * tone.intervalToFrequencyRatio(0); // 1\n\t * tone.intervalToFrequencyRatio(12); // 2\n\t * tone.intervalToFrequencyRatio(-12); // 0.5\n\t */\n\tTone.prototype.intervalToFrequencyRatio = function(interval){\n\t\treturn Math.pow(2,(interval/12));\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTIMING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t */\n\tTone.prototype.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t/**\n\t * Return the current time of the AudioContext clock.\n\t * @return {Number} the currentTime from the AudioContext\n\t * @static\n\t */\n\tTone.now = function(){\n\t\treturn Tone.context.now();\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tINHERITANCE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * have a child inherit all of Tone's (or a parent's) prototype\n\t * to inherit the parent's properties, make sure to call \n\t * Parent.call(this) in the child's constructor\n\t *\n\t * based on closure library's inherit function\n\t *\n\t * @static\n\t * @param {function} \tchild \n\t * @param {function=} parent (optional) parent to inherit from\n\t * if no parent is supplied, the child\n\t * will inherit from Tone\n\t */\n\tTone.extend = function(child, parent){\n\t\tif (Tone.prototype.isUndef(parent)){\n\t\t\tparent = Tone;\n\t\t}\n\t\tfunction TempConstructor(){}\n\t\tTempConstructor.prototype = parent.prototype;\n\t\tchild.prototype = new TempConstructor();\n\t\t/** @override */\n\t\tchild.prototype.constructor = child;\n\t\tchild._super = parent;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tCONTEXT\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The private audio context shared by all Tone Nodes. \n\t * @private\n\t * @type {Tone.Context|undefined}\n\t */\n\tvar audioContext;\n\n\t/**\n\t * A static pointer to the audio context accessible as Tone.context. \n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone\n\t */\n\tObject.defineProperty(Tone, \"context\", {\n\t\tget : function(){\n\t\t\treturn audioContext;\n\t\t},\n\t\tset : function(context){\n\t\t\tif (Tone.Context && context instanceof Tone.Context){\n\t\t\t\taudioContext = context;\n\t\t\t} else {\n\t\t\t\taudioContext = new Tone.Context(context);\n\t\t\t}\n\t\t\t//initialize the new audio context\n\t\t\tif (Tone.Context){\n\t\t\t\tTone.Context.emit(\"init\", audioContext);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * The AudioContext\n\t * @type {Tone.Context}\n\t * @name context\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"context\", {\n\t\tget : function(){\n\t\t\treturn Tone.context;\n\t\t}\n\t});\n\n\t/**\n\t * Tone automatically creates a context on init, but if you are working\n\t * with other libraries which also create an AudioContext, it can be\n\t * useful to set your own. If you are going to set your own context, \n\t * be sure to do it at the start of your code, before creating any objects.\n\t * @static\n\t * @param {AudioContext} ctx The new audio context to set\n\t */\n\tTone.setContext = function(ctx){\n\t\tTone.context = ctx;\n\t};\n\n\t/**\n\t * The number of seconds of 1 processing block (128 samples)\n\t * @type {Number}\n\t * @name blockTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"blockTime\", {\n\t\tget : function(){\n\t\t\treturn 128 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * The duration in seconds of one sample.\n\t * @type {Number}\n\t * @name sampleTime\n\t * @memberOf Tone#\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.prototype, \"sampleTime\", {\n\t\tget : function(){\n\t\t\treturn 1 / this.context.sampleRate;\n\t\t}\n\t});\n\n\t/**\n\t * Whether or not all the technologies that Tone.js relies on are supported by the current browser. \n\t * @type {Boolean}\n\t * @name supported\n\t * @memberOf Tone\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone, \"supported\", {\n\t\tget : function(){\n\t\t\tvar hasAudioContext = window.hasOwnProperty(\"AudioContext\") || window.hasOwnProperty(\"webkitAudioContext\");\n\t\t\tvar hasPromises = window.hasOwnProperty(\"Promise\");\n\t\t\tvar hasWorkers = window.hasOwnProperty(\"Worker\");\n\t\t\treturn hasAudioContext && hasPromises && hasWorkers;\n\t\t}\n\t});\n\n\tTone.version = \"r10\";\n\n\t// allow optional silencing of this log\n\tif (!window.TONE_SILENCE_VERSION_LOGGING) {\n\t\tconsole.log(\"%c * Tone.js \" + Tone.version + \" * \", \"background: #000; color: #fff\");\n\t}\n\n\treturn Tone;\n});\n","'use strict';\n\ndefine(['audiocontext'], function (audiocontext) {\n // Master contains the master sound output.\n var Master = function () {\n this.input = audiocontext.createGain();\n this.output = audiocontext.createGain();\n\n //put a hard limiter on the output\n this.limiter = audiocontext.createDynamicsCompressor();\n this.limiter.threshold.value = -3;\n this.limiter.ratio.value = 20;\n this.limiter.knee.value = 1;\n\n this.audiocontext = audiocontext;\n\n this.output.disconnect();\n\n // connect input to limiter\n this.input.connect(this.limiter);\n\n // connect limiter to output\n this.limiter.connect(this.output);\n\n // meter is just for global Amplitude / FFT analysis\n this.meter = audiocontext.createGain();\n this.fftMeter = audiocontext.createGain();\n this.output.connect(this.meter);\n this.output.connect(this.fftMeter);\n\n // connect output to destination\n this.output.connect(this.audiocontext.destination);\n\n // an array of all sounds in the sketch\n this.soundArray = [];\n // an array of all musical parts in the sketch\n this.parts = [];\n\n // file extensions to search for\n this.extensions = [];\n };\n\n // create a single instance of the p5Sound / master output for use within this sketch\n var p5sound = new Master();\n\n /**\n * Returns a number representing the master amplitude (volume) for sound\n * in this sketch.\n *\n * @method getMasterVolume\n * @return {Number} Master amplitude (volume) for sound in this sketch.\n * Should be between 0.0 (silence) and 1.0.\n */\n p5.prototype.getMasterVolume = function () {\n return p5sound.output.gain.value;\n };\n\n /**\n *

Scale the output of all sound in this sketch

\n * Scaled between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n *

How This Works: When you load the p5.sound module, it\n * creates a single instance of p5sound. All sound objects in this\n * module output to p5sound before reaching your computer's output.\n * So if you change the amplitude of p5sound, it impacts all of the\n * sound in this module.

\n *\n *

If no value is provided, returns a Web Audio API Gain Node

\n *\n * @method masterVolume\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.prototype.masterVolume = function (vol, rampTime = 0, tFromNow = 0) {\n if (typeof vol === 'number') {\n var now = p5sound.audiocontext.currentTime;\n var currentVol = p5sound.output.gain.value;\n p5sound.output.gain.cancelScheduledValues(now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n p5sound.output.gain.linearRampToValueAtTime(\n vol,\n now + tFromNow + rampTime\n );\n } else if (vol) {\n vol.connect(p5sound.output.gain);\n } else {\n // return the Gain Node\n return p5sound.output.gain;\n }\n };\n\n /**\n * `p5.soundOut` is the p5.sound master output. It sends output to\n * the destination of this window's web audio context. It contains\n * Web Audio API nodes including a dyanmicsCompressor (.limiter),\n * and Gain Nodes for .input and .output.\n *\n * @property {Object} soundOut\n */\n p5.prototype.soundOut = p5.soundOut = p5sound;\n\n // a silent connection to the DesinationNode\n // which will ensure that anything connected to it\n // will not be garbage collected\n p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n p5.soundOut._silentNode.gain.value = 0;\n p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n\n return p5sound;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/type/Type\", \"Tone/core/Param\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal is an audio-rate value. Tone.Signal is a core component of the library.\n\t * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n\t * has all of the methods available to native Web Audio \n\t * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n\t * as well as additional conveniences. Read more about working with signals \n\t * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n\t *\n\t * @constructor\n\t * @extends {Tone.Param}\n\t * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam\n\t * is passed in, that parameter will be wrapped\n\t * and controlled by the Signal. \n\t * @param {string} [units=Number] unit The units the signal is in. \n\t * @example\n\t * var signal = new Tone.Signal(10);\n\t */\n\tTone.Signal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\n\t\t/**\n\t\t * The node where the constant signal value is scaled.\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.output = this._gain = this.context.createGain();\n\n\t\toptions.param = this._gain.gain;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The node where the value is set.\n\t\t * @type {Tone.Param}\n\t\t * @private\n\t\t */\n\t\tthis.input = this._param = this._gain.gain;\n\n\t\t//connect the const output to the node output\n\t\tthis.context.getConstant(1).chain(this._gain);\n\t};\n\n\tTone.extend(Tone.Signal, Tone.Param);\n\n\t/**\n\t * The default values\n\t * @type {Object}\n\t * @static\n\t * @const\n\t */\n\tTone.Signal.defaults = {\n\t\t\"value\" : 0,\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t * @method\n\t */\n\tTone.Signal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\t/**\n\t * dispose and disconnect\n\t * @returns {Tone.Signal} this\n\t */\n\tTone.Signal.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tthis._gain.disconnect();\n\t\tthis._gain = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Signal;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Multiply two incoming signals. Or, if a number is given in the constructor, \n\t * multiplies the incoming signal by that value. \n\t *\n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value Constant value to multiple. If no value is provided,\n\t * it will return the product of the first and second inputs\n\t * @example\n\t * var mult = new Tone.Multiply();\n\t * var sigA = new Tone.Signal(3);\n\t * var sigB = new Tone.Signal(4);\n\t * sigA.connect(mult, 0, 0);\n\t * sigB.connect(mult, 0, 1);\n\t * //output of mult is 12.\n\t * @example\n\t * var mult = new Tone.Multiply(10);\n\t * var sig = new Tone.Signal(2).connect(mult);\n\t * //the output of mult is 20. \n\t */\n\tTone.Multiply = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the input node is the same as the output node\n\t\t * it is also the GainNode which handles the scaling of incoming signal\n\t\t * \n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._mult = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * the scaling parameter\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[1] = this.output.gain;\n\t\t\n\t\tthis._param.value = this.defaultArg(value, 0);\n\t};\n\n\tTone.extend(Tone.Multiply, Tone.Signal);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Multiply} this\n\t */\n\tTone.Multiply.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._mult.dispose();\n\t\tthis._mult = null;\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Multiply;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/SignalBase\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Wraps the native Web Audio API \n\t * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {function|Array|Number} mapping The function used to define the values. \n\t * The mapping function should take two arguments: \n\t * the first is the value at the current position \n\t * and the second is the array position. \n\t * If the argument is an array, that array will be\n\t * set as the wave shaping function. The input\n\t * signal is an AudioRange [-1, 1] value and the output\n\t * signal can take on any numerical values. \n\t * \n\t * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer.\n\t * @example\n\t * var timesTwo = new Tone.WaveShaper(function(val){\n\t * \treturn val * 2;\n\t * }, 2048);\n\t * @example\n\t * //a waveshaper can also be constructed with an array of values\n\t * var invert = new Tone.WaveShaper([1, -1]);\n\t */\n\tTone.WaveShaper = function(mapping, bufferLen){\n\n\t\t/**\n\t\t * the waveshaper\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._shaper = this.input = this.output = this.context.createWaveShaper();\n\n\t\t/**\n\t\t * the waveshapers curve\n\t\t * @type {Float32Array}\n\t\t * @private\n\t\t */\n\t\tthis._curve = null;\n\n\t\tif (Array.isArray(mapping)){\n\t\t\tthis.curve = mapping;\n\t\t} else if (isFinite(mapping) || this.isUndef(mapping)){\n\t\t\tthis._curve = new Float32Array(this.defaultArg(mapping, 1024));\n\t\t} else if (this.isFunction(mapping)){\n\t\t\tthis._curve = new Float32Array(this.defaultArg(bufferLen, 1024));\n\t\t\tthis.setMap(mapping);\n\t\t} \n\t};\n\n\tTone.extend(Tone.WaveShaper, Tone.SignalBase);\n\n\t/**\n\t * Uses a mapping function to set the value of the curve. \n\t * @param {function} mapping The function used to define the values. \n\t * The mapping function take two arguments: \n\t * the first is the value at the current position \n\t * which goes from -1 to 1 over the number of elements\n\t * in the curve array. The second argument is the array position. \n\t * @returns {Tone.WaveShaper} this\n\t * @example\n\t * //map the input signal from [-1, 1] to [0, 10]\n\t * shaper.setMap(function(val, index){\n\t * \treturn (val + 1) * 5;\n\t * })\n\t */\n\tTone.WaveShaper.prototype.setMap = function(mapping){\n\t\tfor (var i = 0, len = this._curve.length; i < len; i++){\n\t\t\tvar normalized = (i / (len - 1)) * 2 - 1;\n\t\t\tthis._curve[i] = mapping(normalized, i);\n\t\t}\n\t\tthis._shaper.curve = this._curve;\n\t\treturn this;\n\t};\n\n\t/**\n\t * The array to set as the waveshaper curve. For linear curves\n\t * array length does not make much difference, but for complex curves\n\t * longer arrays will provide smoother interpolation. \n\t * @memberOf Tone.WaveShaper#\n\t * @type {Array}\n\t * @name curve\n\t */\n\tObject.defineProperty(Tone.WaveShaper.prototype, \"curve\", {\n\t\tget : function(){\n\t\t\treturn this._shaper.curve;\n\t\t},\n\t\tset : function(mapping){\n\t\t\tthis._curve = new Float32Array(mapping);\n\t\t\tthis._shaper.curve = this._curve;\n\t\t}\n\t});\n\n\t/**\n\t * Specifies what type of oversampling (if any) should be used when \n\t * applying the shaping curve. Can either be \"none\", \"2x\" or \"4x\". \n\t * @memberOf Tone.WaveShaper#\n\t * @type {string}\n\t * @name oversample\n\t */\n\tObject.defineProperty(Tone.WaveShaper.prototype, \"oversample\", {\n\t\tget : function(){\n\t\t\treturn this._shaper.oversample;\n\t\t},\n\t\tset : function(oversampling){\n\t\t\tif ([\"none\", \"2x\", \"4x\"].indexOf(oversampling) !== -1){\n\t\t\t\tthis._shaper.oversample = oversampling;\n\t\t\t} else {\n\t\t\t\tthrow new RangeError(\"Tone.WaveShaper: oversampling must be either 'none', '2x', or '4x'\");\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.WaveShaper} this\n\t */\n\tTone.WaveShaper.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.disconnect();\n\t\tthis._shaper = null;\n\t\tthis._curve = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.WaveShaper;\n});","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var CrossFade = require('Tone/component/CrossFade');\n\n /**\n * Effect is a base class for audio effects in p5.
\n * This module handles the nodes and methods that are\n * common and useful for current and future effects.\n *\n *\n * This class is extended by p5.Distortion,\n * p5.Compressor,\n * p5.Delay,\n * p5.Filter,\n * p5.Reverb.\n *\n * @class p5.Effect\n * @constructor\n *\n * @param {Object} [ac] Reference to the audio context of the p5 object\n * @param {AudioNode} [input] Gain Node effect wrapper\n * @param {AudioNode} [output] Gain Node effect wrapper\n * @param {Object} [_drywet] Tone.JS CrossFade node (defaults to value: 1)\n * @param {AudioNode} [wet] Effects that extend this class should connect\n * to the wet signal to this gain node, so that dry and wet\n * signals are mixed properly.\n */\n p5.Effect = function () {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n /**\n *\tThe p5.Effect class is built\n * \tusing Tone.js CrossFade\n * \t@private\n */\n\n this._drywet = new CrossFade(1);\n\n /**\n *\tIn classes that extend\n *\tp5.Effect, connect effect nodes\n *\tto the wet parameter\n */\n this.wet = this.ac.createGain();\n\n this.input.connect(this._drywet.a);\n this.wet.connect(this._drywet.b);\n this._drywet.connect(this.output);\n\n this.connect();\n\n //Add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the output volume of the filter.\n *\n * @method amp\n * @for p5.Effect\n * @param {Number} [vol] amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts until rampTime\n * @param {Number} [tFromNow] schedule this event to happen in tFromNow seconds\n */\n p5.Effect.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n const now = p5sound.audiocontext.currentTime;\n const startTime = now + tFromNow;\n const endTime = startTime + rampTime + 0.001;\n const currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, startTime + 0.001);\n this.output.gain.linearRampToValueAtTime(vol, endTime);\n };\n\n /**\n * Link effects together in a chain\n * Example usage: filter.chain(reverb, delay, panner);\n * May be used with an open-ended number of arguments\n *\n * @method chain\n * @for p5.Effect\n * @param {Object} [arguments] Chain together multiple sound objects\n */\n p5.Effect.prototype.chain = function () {\n if (arguments.length > 0) {\n this.connect(arguments[0]);\n for (var i = 1; i < arguments.length; i += 1) {\n arguments[i - 1].connect(arguments[i]);\n }\n }\n return this;\n };\n\n /**\n * Adjust the dry/wet value.\n *\n * @method drywet\n * @for p5.Effect\n * @param {Number} [fade] The desired drywet value (0 - 1.0)\n */\n p5.Effect.prototype.drywet = function (fade) {\n if (typeof fade !== 'undefined') {\n this._drywet.fade.value = fade;\n }\n return this._drywet.fade.value;\n };\n\n /**\n * Send output to a p5.js-sound, Web Audio Node, or use signal to\n * control an AudioParam\n *\n * @method connect\n * @for p5.Effect\n * @param {Object} unit\n */\n p5.Effect.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n * @method disconnect\n * @for p5.Effect\n */\n p5.Effect.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n p5.Effect.prototype.dispose = function () {\n // remove refernce form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n if (this._drywet) {\n this._drywet.disconnect();\n delete this._drywet;\n }\n\n if (this.wet) {\n this.wet.disconnect();\n delete this.wet;\n }\n\n this.ac = undefined;\n };\n\n return p5.Effect;\n});\n","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var processorNames = require('./audioWorklet/processorNames');\n /**\n * @for p5\n */\n\n /**\n * Returns a number representing the sample rate, in samples per second,\n * of all sound objects in this audio context. It is determined by the\n * sampling rate of your operating system's sound card, and it is not\n * currently possile to change.\n * It is often 44100, or twice the range of human hearing.\n *\n * @method sampleRate\n * @return {Number} samplerate samples per second\n */\n p5.prototype.sampleRate = function () {\n return p5sound.audiocontext.sampleRate;\n };\n\n /**\n * Returns the closest MIDI note value for\n * a given frequency.\n *\n * @method freqToMidi\n * @param {Number} frequency A freqeuncy, for example, the \"A\"\n * above Middle C is 440Hz\n * @return {Number} MIDI note value\n */\n p5.prototype.freqToMidi = function (f) {\n var mathlog2 = Math.log(f / 440) / Math.log(2);\n var m = Math.round(12 * mathlog2) + 69;\n return m;\n };\n\n /**\n * Returns the frequency value of a MIDI note value.\n * General MIDI treats notes as integers where middle C\n * is 60, C# is 61, D is 62 etc. Useful for generating\n * musical frequencies with oscillators.\n *\n * @method midiToFreq\n * @param {Number} midiNote The number of a MIDI note\n * @return {Number} Frequency value of the given MIDI note\n * @example\n *
\n * let midiNotes = [60, 64, 67, 72];\n * let noteIndex = 0;\n * let midiVal, freq;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * osc = new p5.TriOsc();\n * env = new p5.Envelope();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 10, 20);\n * if (midiVal) {\n * text('MIDI: ' + midiVal, 10, 40);\n * text('Freq: ' + freq, 10, 60);\n * }\n * }\n *\n * function startSound() {\n * // see also: userStartAudio();\n * osc.start();\n *\n * midiVal = midiNotes[noteIndex % midiNotes.length];\n * freq = midiToFreq(midiVal);\n * osc.freq(freq);\n * env.ramp(osc, 0, 1.0, 0);\n *\n * noteIndex++;\n * }\n *
\n */\n var midiToFreq = (p5.prototype.midiToFreq = function (m) {\n return 440 * Math.pow(2, (m - 69) / 12.0);\n });\n\n // This method converts ANSI notes specified as a string \"C4\", \"Eb3\" to a frequency\n var noteToFreq = function (note) {\n if (typeof note !== 'string') {\n return note;\n }\n var wholeNotes = { A: 21, B: 23, C: 24, D: 26, E: 28, F: 29, G: 31 };\n var value = wholeNotes[note[0].toUpperCase()];\n var octave = ~~note.slice(-1);\n value += 12 * (octave - 1);\n\n switch (note[1]) {\n case '#':\n value += 1;\n break;\n case 'b':\n value -= 1;\n break;\n default:\n break;\n }\n return midiToFreq(value);\n };\n\n /**\n * List the SoundFile formats that you will include. LoadSound\n * will search your directory for these extensions, and will pick\n * a format that is compatable with the client's web browser.\n * Here is a free online file\n * converter.\n *\n * @method soundFormats\n * @param {String} [...formats] i.e. 'mp3', 'wav', 'ogg'\n * @example\n *
\n * function preload() {\n * // set the global sound formats\n * soundFormats('mp3', 'ogg');\n *\n * // load either beatbox.mp3, or .ogg, depending on browser\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('sound loaded! tap to play', 10, 20, width - 20);\n * cnv.mousePressed(function() {\n * mySound.play();\n * });\n * }\n *
\n */\n p5.prototype.soundFormats = function () {\n // reset extensions array\n p5sound.extensions = [];\n // add extensions\n for (var i = 0; i < arguments.length; i++) {\n arguments[i] = arguments[i].toLowerCase();\n if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(arguments[i]) > -1) {\n p5sound.extensions.push(arguments[i]);\n } else {\n throw arguments[i] + ' is not a valid sound format!';\n }\n }\n };\n\n p5.prototype.disposeSound = function () {\n for (var i = 0; i < p5sound.soundArray.length; i++) {\n p5sound.soundArray[i].dispose();\n }\n };\n\n // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n // Oscillators etc when sketch ends\n p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n\n p5.prototype._checkFileFormats = function (paths) {\n var path;\n // if path is a single string, check to see if extension is provided\n if (typeof paths === 'string') {\n path = paths;\n // see if extension is provided\n var extTest = path.split('.').pop();\n // if an extension is provided...\n if (['mp3', 'wav', 'ogg', 'm4a', 'aac'].indexOf(extTest) > -1) {\n if (!p5.prototype.isFileSupported(extTest)) {\n var pathSplit = path.split('.');\n var pathCore = pathSplit[pathSplit.length - 1];\n for (let i = 0; i < p5sound.extensions.length; i++) {\n const extension = p5sound.extensions[i];\n const supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n pathCore = '';\n if (pathSplit.length === 2) {\n pathCore += pathSplit[0];\n }\n for (let i = 1; i <= pathSplit.length - 2; i++) {\n var p = pathSplit[i];\n pathCore += '.' + p;\n }\n path = pathCore += '.';\n path = path += extension;\n break;\n }\n }\n }\n }\n // if no extension is provided...\n else {\n for (let i = 0; i < p5sound.extensions.length; i++) {\n const extension = p5sound.extensions[i];\n const supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n path = path + '.' + extension;\n break;\n }\n }\n }\n } // end 'if string'\n\n // path can either be a single string, or an array\n else if (typeof paths === 'object') {\n for (var i = 0; i < paths.length; i++) {\n var extension = paths[i].split('.').pop();\n var supported = p5.prototype.isFileSupported(extension);\n if (supported) {\n // console.log('.'+extension + ' is ' + supported +\n // ' supported by your browser.');\n path = paths[i];\n break;\n }\n }\n }\n return path;\n };\n\n /**\n * Used by Osc and Envelope to chain signal math\n */\n p5.prototype._mathChain = function (o, math, thisChain, nextChain, type) {\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n o.mathOps[i].dispose();\n thisChain = i;\n if (thisChain < o.mathOps.length - 1) {\n nextChain = o.mathOps[i + 1];\n }\n }\n }\n o.mathOps[thisChain - 1].disconnect();\n o.mathOps[thisChain - 1].connect(math);\n math.connect(nextChain);\n o.mathOps[thisChain] = math;\n return o;\n };\n\n // helper methods to convert audio file as .wav format,\n // will use as saving .wav file and saving blob object\n // Thank you to Matt Diamond's RecorderJS (MIT License)\n // https://github.com/mattdiamond/Recorderjs\n function convertToWav(audioBuffer) {\n var leftChannel, rightChannel;\n leftChannel = audioBuffer.getChannelData(0);\n\n // handle mono files\n if (audioBuffer.numberOfChannels > 1) {\n rightChannel = audioBuffer.getChannelData(1);\n } else {\n rightChannel = leftChannel;\n }\n\n var interleaved = interleave(leftChannel, rightChannel);\n\n // create the buffer and view to create the .WAV file\n var buffer = new window.ArrayBuffer(44 + interleaved.length * 2);\n var view = new window.DataView(buffer);\n\n // write the WAV container,\n // check spec at: https://web.archive.org/web/20171215131933/http://tiny.systems/software/soundProgrammer/WavFormatDocs.pdf\n\n // RIFF chunk descriptor\n writeUTFBytes(view, 0, 'RIFF');\n view.setUint32(4, 36 + interleaved.length * 2, true);\n writeUTFBytes(view, 8, 'WAVE');\n // FMT sub-chunk\n writeUTFBytes(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n // stereo (2 channels)\n view.setUint16(22, 2, true);\n view.setUint32(24, p5sound.audiocontext.sampleRate, true);\n view.setUint32(28, p5sound.audiocontext.sampleRate * 4, true);\n view.setUint16(32, 4, true);\n view.setUint16(34, 16, true);\n // data sub-chunk\n writeUTFBytes(view, 36, 'data');\n view.setUint32(40, interleaved.length * 2, true);\n\n // write the PCM samples\n var lng = interleaved.length;\n var index = 44;\n var volume = 1;\n for (var i = 0; i < lng; i++) {\n view.setInt16(index, interleaved[i] * (0x7fff * volume), true);\n index += 2;\n }\n\n return view;\n }\n\n // helper methods to save waves\n function interleave(leftChannel, rightChannel) {\n var length = leftChannel.length + rightChannel.length;\n var result = new Float32Array(length);\n\n var inputIndex = 0;\n\n for (var index = 0; index < length; ) {\n result[index++] = leftChannel[inputIndex];\n result[index++] = rightChannel[inputIndex];\n inputIndex++;\n }\n return result;\n }\n\n function writeUTFBytes(view, offset, string) {\n var lng = string.length;\n for (var i = 0; i < lng; i++) {\n view.setUint8(offset + i, string.charCodeAt(i));\n }\n }\n\n function safeBufferSize(idealBufferSize) {\n let bufferSize = idealBufferSize;\n\n // if the AudioWorkletNode is actually a ScriptProcessorNode created via polyfill,\n // make sure that our chosen buffer size isn't smaller than the buffer size automatically\n // selected by the polyfill\n // reference: https://github.com/GoogleChromeLabs/audioworklet-polyfill/issues/13#issuecomment-425014930\n let tempAudioWorkletNode = new AudioWorkletNode(\n p5sound.audiocontext,\n processorNames.soundFileProcessor\n );\n if (tempAudioWorkletNode instanceof ScriptProcessorNode) {\n bufferSize = tempAudioWorkletNode.bufferSize;\n }\n tempAudioWorkletNode.disconnect();\n tempAudioWorkletNode = null;\n\n return bufferSize;\n }\n\n return {\n convertToWav: convertToWav,\n midiToFreq: midiToFreq,\n noteToFreq: noteToFreq,\n safeBufferSize: safeBufferSize,\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Add a signal and a number or two signals. When no value is\n\t * passed into the constructor, Tone.Add will sum input[0]\n\t * and input[1]. If a value is passed into the constructor, \n\t * the it will be added to the input.\n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number=} value If no value is provided, Tone.Add will sum the first\n\t * and second inputs. \n\t * @example\n\t * var signal = new Tone.Signal(2);\n\t * var add = new Tone.Add(2);\n\t * signal.connect(add);\n\t * //the output of add equals 4\n\t * @example\n\t * //if constructed with no arguments\n\t * //it will add the first and second inputs\n\t * var add = new Tone.Add();\n\t * var sig0 = new Tone.Signal(3).connect(add, 0, 0);\n\t * var sig1 = new Tone.Signal(4).connect(add, 0, 1);\n\t * //the output of add equals 7. \n\t */\n\tTone.Add = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.connect(this._sum);\n\t};\n\n\tTone.extend(Tone.Add, Tone.Signal);\n\t\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Add} this\n\t */\n\tTone.Add.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._sum.dispose();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Add;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\", \"Tone/type/Frequency\", \"Tone/type/TransportTime\", \"Tone/core/Context\"],\nfunction (Tone) {\t\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tTYPES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Units which a value can take on.\n\t * @enum {String}\n\t */\n\tTone.Type = {\n\t\t/** \n\t\t * Default units\n\t\t * @typedef {Default}\n\t\t */\n\t\tDefault : \"number\",\n\t\t/**\n\t\t * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time).\n\t\t *\n\t\t *
    \n\t\t *
  • Numbers, which will be taken literally as the time (in seconds).
  • \n\t\t *
  • Notation, (\"4n\", \"8t\") describes time in BPM and time signature relative values.
  • \n\t\t *
  • TransportTime, (\"4:3:2\") will also provide tempo and time signature relative times \n\t\t * in the form BARS:QUARTERS:SIXTEENTHS.
  • \n\t\t *
  • Frequency, (\"8hz\") is converted to the length of the cycle in seconds.
  • \n\t\t *
  • Now-Relative, (\"+1\") prefix any of the above with \"+\" and it will be interpreted as \n\t\t * \"the current time plus whatever expression follows\".
  • \n\t\t *
  • Expressions, (\"3:0 + 2 - (1m / 7)\") any of the above can also be combined \n\t\t * into a mathematical expression which will be evaluated to compute the desired time.
  • \n\t\t *
  • No Argument, for methods which accept time, no argument will be interpreted as \n\t\t * \"now\" (i.e. the currentTime).
  • \n\t\t *
\n\t\t * \n\t\t * @typedef {Time}\n\t\t */\n\t\tTime : \"time\",\n\t\t/**\n\t\t * Frequency can be described similar to time, except ultimately the\n\t\t * values are converted to frequency instead of seconds. A number\n\t\t * is taken literally as the value in hertz. Additionally any of the \n\t\t * Time encodings can be used. Note names in the form\n\t\t * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their\n\t\t * frequency value. \n\t\t * @typedef {Frequency}\n\t\t */\n\t\tFrequency : \"frequency\",\n\t\t/**\n\t\t * TransportTime describes a position along the Transport's timeline. It is\n\t\t * similar to Time in that it uses all the same encodings, but TransportTime specifically\n\t\t * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. \n\t\t * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime)\n\t\t * @typedef {TransportTime}\n\t\t */\n\t\tTransportTime : \"transportTime\",\n\t\t/** \n\t\t * Ticks are the basic subunit of the Transport. They are\n\t\t * the smallest unit of time that the Transport supports.\n\t\t * @typedef {Ticks}\n\t\t */\n\t\tTicks : \"ticks\",\n\t\t/** \n\t\t * Normal values are within the range [0, 1].\n\t\t * @typedef {NormalRange}\n\t\t */\n\t\tNormalRange : \"normalRange\",\n\t\t/** \n\t\t * AudioRange values are between [-1, 1].\n\t\t * @typedef {AudioRange}\n\t\t */\n\t\tAudioRange : \"audioRange\",\n\t\t/** \n\t\t * Decibels are a logarithmic unit of measurement which is useful for volume\n\t\t * because of the logarithmic way that we perceive loudness. 0 decibels \n\t\t * means no change in volume. -10db is approximately half as loud and 10db \n\t\t * is twice is loud. \n\t\t * @typedef {Decibels}\n\t\t */\n\t\tDecibels : \"db\",\n\t\t/** \n\t\t * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up.\n\t\t * @typedef {Interval}\n\t\t */\n\t\tInterval : \"interval\",\n\t\t/** \n\t\t * Beats per minute. \n\t\t * @typedef {BPM}\n\t\t */\n\t\tBPM : \"bpm\",\n\t\t/** \n\t\t * The value must be greater than or equal to 0.\n\t\t * @typedef {Positive}\n\t\t */\n\t\tPositive : \"positive\",\n\t\t/** \n\t\t * A cent is a hundredth of a semitone. \n\t\t * @typedef {Cents}\n\t\t */\n\t\tCents : \"cents\",\n\t\t/** \n\t\t * Angle between 0 and 360. \n\t\t * @typedef {Degrees}\n\t\t */\n\t\tDegrees : \"degrees\",\n\t\t/** \n\t\t * A number representing a midi note.\n\t\t * @typedef {MIDI}\n\t\t */\n\t\tMIDI : \"midi\",\n\t\t/** \n\t\t * A colon-separated representation of time in the form of\n\t\t * Bars:Beats:Sixteenths. \n\t\t * @typedef {BarsBeatsSixteenths}\n\t\t */\n\t\tBarsBeatsSixteenths : \"barsBeatsSixteenths\",\n\t\t/** \n\t\t * Sampling is the reduction of a continuous signal to a discrete signal.\n\t\t * Audio is typically sampled 44100 times per second. \n\t\t * @typedef {Samples}\n\t\t */\n\t\tSamples : \"samples\",\n\t\t/** \n\t\t * Hertz are a frequency representation defined as one cycle per second.\n\t\t * @typedef {Hertz}\n\t\t */\n\t\tHertz : \"hertz\",\n\t\t/** \n\t\t * A frequency represented by a letter name, \n\t\t * accidental and octave. This system is known as\n\t\t * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation).\n\t\t * @typedef {Note}\n\t\t */\n\t\tNote : \"note\",\n\t\t/** \n\t\t * One millisecond is a thousandth of a second. \n\t\t * @typedef {Milliseconds}\n\t\t */\n\t\tMilliseconds : \"milliseconds\",\n\t\t/** \n\t\t * Seconds are the time unit of the AudioContext. In the end, \n\t\t * all values need to be evaluated to seconds. \n\t\t * @typedef {Seconds}\n\t\t */\n\t\tSeconds : \"seconds\",\n\t\t/** \n\t\t * A string representing a duration relative to a measure. \n\t\t *
    \n\t\t * \t
  • \"4n\" = quarter note
  • \n\t\t * \t
  • \"2m\" = two measures
  • \n\t\t * \t
  • \"8t\" = eighth-note triplet
  • \n\t\t *
\n\t\t * @typedef {Notation}\n\t\t */\n\t\tNotation : \"notation\",\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// AUGMENT TONE's PROTOTYPE\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert Time into seconds.\n\t * \n\t * Unlike the method which it overrides, this takes into account \n\t * transporttime and musical notation.\n\t *\n\t * Time : 1.40\n\t * Notation: 4n|1m|2t\n\t * Now Relative: +3n\n\t * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1)\n\t *\n\t * @param {Time} time \n\t * @return {Seconds} \n\t */\n\tTone.prototype.toSeconds = function(time){\n\t\tif (this.isNumber(time)){\n\t\t\treturn time;\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn this.now();\t\t\t\n\t\t} else if (this.isString(time)){\n\t\t\treturn (new Tone.Time(time)).toSeconds();\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toSeconds();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a frequency representation into a number.\n\t * @param {Frequency} freq \n\t * @return {Hertz} the frequency in hertz\n\t */\n\tTone.prototype.toFrequency = function(freq){\n\t\tif (this.isNumber(freq)){\n\t\t\treturn freq;\n\t\t} else if (this.isString(freq) || this.isUndef(freq)){\n\t\t\treturn (new Tone.Frequency(freq)).valueOf();\n\t\t} else if (freq instanceof Tone.TimeBase){\n\t\t\treturn freq.toFrequency();\n\t\t}\n\t};\n\n\t/**\n\t * Convert a time representation into ticks.\n\t * @param {Time} time\n\t * @return {Ticks} the time in ticks\n\t */\n\tTone.prototype.toTicks = function(time){\n\t\tif (this.isNumber(time) || this.isString(time)){\n\t\t\treturn (new Tone.TransportTime(time)).toTicks();\n\t\t} else if (this.isUndef(time)){\n\t\t\treturn Tone.Transport.ticks;\t\t\t\n\t\t} else if (time instanceof Tone.TimeBase){\n\t\t\treturn time.toTicks();\n\t\t}\n\t};\n\n\treturn Tone;\n});","define([\"Tone/core/Tone\", \"Tone/core/Param\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * createGain shim\n\t * @private\n\t */\n\tif (window.GainNode && !AudioContext.prototype.createGain){\n\t\tAudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n\t}\n\n\t/**\n\t * @class A thin wrapper around the Native Web Audio GainNode.\n\t * The GainNode is a basic building block of the Web Audio\n\t * API and is useful for routing audio and adjusting gains. \n\t * @extends {Tone}\n\t * @param {Number=} gain The initial gain of the GainNode\n\t * @param {Tone.Type=} units The units of the gain parameter. \n\t */\n\tTone.Gain = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"gain\", \"units\"], Tone.Gain.defaults);\n\n\t\t/**\n\t\t * The GainNode\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis.input = this.output = this._gainNode = this.context.createGain();\n\n\t\t/**\n\t\t * The gain parameter of the gain node.\n\t\t * @type {Tone.Param}\n\t\t * @signal\n\t\t */\n\t\tthis.gain = new Tone.Param({\n\t\t\t\"param\" : this._gainNode.gain, \n\t\t\t\"units\" : options.units,\n\t\t\t\"value\" : options.gain,\n\t\t\t\"convert\" : options.convert\n\t\t});\n\t\tthis._readOnly(\"gain\");\n\t};\n\n\tTone.extend(Tone.Gain);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Gain.defaults = {\n\t\t\"gain\" : 1,\n\t\t\"convert\" : true,\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Gain} this\n\t */\n\tTone.Gain.prototype.dispose = function(){\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._gainNode.disconnect();\n\t\tthis._gainNode = null;\n\t\tthis._writable(\"gain\");\n\t\tthis.gain.dispose();\n\t\tthis.gain = null;\n\t};\n\n\t//STATIC///////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Create input and outputs for this object.\n\t * @param {Number} input The number of inputs\n\t * @param {Number=} outputs The number of outputs\n\t * @return {Tone} this\n\t * @internal\n\t */\n\tTone.prototype.createInsOuts = function(inputs, outputs){\n\n\t\tif (inputs === 1){\n\t\t\tthis.input = new Tone.Gain();\n\t\t} else if (inputs > 1){\n\t\t\tthis.input = new Array(inputs);\n\t\t}\n\n\t\tif (outputs === 1){\n\t\t\tthis.output = new Tone.Gain();\n\t\t} else if (outputs > 1){\n\t\t\tthis.output = new Array(inputs);\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\n\treturn Tone.Gain;\n});","module.exports = {\n recorderProcessor: 'recorder-processor',\n soundFileProcessor: 'sound-file-processor',\n amplitudeProcessor: 'amplitude-processor',\n};\n","define([\"Tone/core/Tone\", \"Tone/core/Emitter\"], function (Tone) {\n\n\t/**\n\t * shim\n\t * @private\n\t */\n\tif (!window.hasOwnProperty(\"AudioContext\") && window.hasOwnProperty(\"webkitAudioContext\")){\n\t\twindow.AudioContext = window.webkitAudioContext;\n\t}\n\n\t/**\n\t * @class Wrapper around the native AudioContext.\n\t * @extends {Tone.Emitter}\n\t * @param {AudioContext=} context optionally pass in a context\n\t */\n\tTone.Context = function(context){\n\n\t\tTone.Emitter.call(this);\n\n\t\tif (!context){\n\t\t\tcontext = new window.AudioContext();\n\t\t}\n\t\tthis._context = context;\n\t\t// extend all of the methods\n\t\tfor (var prop in this._context){\n\t\t\tthis._defineProperty(this._context, prop);\n\t\t}\n\n\t\t///////////////////////////////////////////////////////////////////////\n\t\t// WORKER\n\t\t///////////////////////////////////////////////////////////////////////\n\n\t\t/**\n\t\t * The default latency hint\n\t\t * @type {String}\n\t\t * @private\n\t\t */\n\t\tthis._latencyHint = \"interactive\";\n\n\t\t/**\n\t\t * The amount of time events are scheduled\n\t\t * into the future\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._lookAhead = 0.1;\n\n\t\t/**\n\t\t * How often the update look runs\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._updateInterval = this._lookAhead/3;\n\n\t\t/**\n\t\t * A reference to the actual computed update interval\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._computedUpdateInterval = 0;\n\n\t\t/**\n\t\t * The web worker which is used to update Tone.Clock\n\t\t * @private\n\t\t * @type {WebWorker}\n\t\t */\n\t\tthis._worker = this._createWorker();\n\n\t\t/**\n\t\t * An object containing all of the constants AudioBufferSourceNodes\n\t\t * @type {Object}\n\t\t * @private\n\t\t */\n\t\tthis._constants = {};\n\n\t};\n\n\tTone.extend(Tone.Context, Tone.Emitter);\n\tTone.Emitter.mixin(Tone.Context);\n\n\t/**\n\t * Define a property on this Tone.Context. \n\t * This is used to extend the native AudioContext\n\t * @param {AudioContext} context\n\t * @param {String} prop \n\t * @private\n\t */\n\tTone.Context.prototype._defineProperty = function(context, prop){\n\t\tif (this.isUndef(this[prop])){\n\t\t\tObject.defineProperty(this, prop, {\n\t\t\t\tget : function(){\n\t\t\t\t\tif (typeof context[prop] === \"function\"){\n\t\t\t\t\t\treturn context[prop].bind(context);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn context[prop];\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tset : function(val){\n\t\t\t\t\tcontext[prop] = val;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t/**\n\t * The current audio context time\n\t * @return {Number}\n\t */\n\tTone.Context.prototype.now = function(){\n\t\treturn this._context.currentTime;\n\t};\n\n\t/**\n\t * Generate a web worker\n\t * @return {WebWorker}\n\t * @private\n\t */\n\tTone.Context.prototype._createWorker = function(){\n\t\t\n\t\t//URL Shim\n\t\twindow.URL = window.URL || window.webkitURL;\n\n\t\tvar blob = new Blob([\n\t\t\t//the initial timeout time\n\t\t\t\"var timeoutTime = \"+(this._updateInterval * 1000).toFixed(1)+\";\" +\n\t\t\t//onmessage callback\n\t\t\t\"self.onmessage = function(msg){\" +\n\t\t\t\"\ttimeoutTime = parseInt(msg.data);\" + \n\t\t\t\"};\" + \n\t\t\t//the tick function which posts a message\n\t\t\t//and schedules a new tick\n\t\t\t\"function tick(){\" +\n\t\t\t\"\tsetTimeout(tick, timeoutTime);\" +\n\t\t\t\"\tself.postMessage('tick');\" +\n\t\t\t\"}\" +\n\t\t\t//call tick initially\n\t\t\t\"tick();\"\n\t\t]);\n\t\tvar blobUrl = URL.createObjectURL(blob);\n\t\tvar worker = new Worker(blobUrl);\n\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\t// tick the clock\n\t\t\tthis.emit(\"tick\");\n\t\t}.bind(this));\n\n\t\t//lag compensation\n\t\tworker.addEventListener(\"message\", function(){\n\t\t\tvar now = this.now();\n\t\t\tif (this.isNumber(this._lastUpdate)){\n\t\t\t\tvar diff = now - this._lastUpdate;\n\t\t\t\tthis._computedUpdateInterval = Math.max(diff, this._computedUpdateInterval * 0.97);\n\t\t\t}\n\t\t\tthis._lastUpdate = now;\n\t\t}.bind(this));\n\n\t\treturn worker;\n\t};\n\n\t/**\n\t * Generate a looped buffer at some constant value.\n\t * @param {Number} val\n\t * @return {BufferSourceNode}\n\t */\n\tTone.Context.prototype.getConstant = function(val){\n\t\tif (this._constants[val]){\n\t\t\treturn this._constants[val];\n\t\t} else {\n\t\t\tvar buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n\t\t\tvar arr = buffer.getChannelData(0);\n\t\t\tfor (var i = 0; i < arr.length; i++){\n\t\t\t\tarr[i] = val;\n\t\t\t}\n\t\t\tvar constant = this._context.createBufferSource();\n\t\t\tconstant.channelCount = 1;\n\t\t\tconstant.channelCountMode = \"explicit\";\n\t\t\tconstant.buffer = buffer;\n\t\t\tconstant.loop = true;\n\t\t\tconstant.start(0);\n\t\t\tthis._constants[val] = constant;\n\t\t\treturn constant;\n\t\t}\n\t};\n\n\t/**\n\t * This is the time that the clock is falling behind\n\t * the scheduled update interval. The Context automatically\n\t * adjusts for the lag and schedules further in advance.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lag\n\t * @static\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lag\", {\n\t\tget : function(){\n\t\t\tvar diff = this._computedUpdateInterval - this._updateInterval;\n\t\t\tdiff = Math.max(diff, 0);\n\t\t\treturn diff;\n\t\t}\n\t});\n\n\t/**\n\t * The amount of time in advance that events are scheduled.\n\t * The lookAhead will adjust slightly in response to the \n\t * measured update time to try to avoid clicks.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name lookAhead\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"lookAhead\", {\n\t\tget : function(){\n\t\t\treturn this._lookAhead;\n\t\t},\n\t\tset : function(lA){\n\t\t\tthis._lookAhead = lA;\n\t\t}\n\t});\n\n\t/**\n\t * How often the Web Worker callback is invoked.\n\t * This number corresponds to how responsive the scheduling\n\t * can be. Context.updateInterval + Context.lookAhead gives you the\n\t * total latency between scheduling an event and hearing it.\n\t * @type {Number}\n\t * @memberOf Tone.Context\n\t * @name updateInterval\n\t * @static\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"updateInterval\", {\n\t\tget : function(){\n\t\t\treturn this._updateInterval;\n\t\t},\n\t\tset : function(interval){\n\t\t\tthis._updateInterval = Math.max(interval, Tone.prototype.blockTime);\n\t\t\tthis._worker.postMessage(Math.max(interval * 1000, 1));\n\t\t}\n\t});\n\n\t/**\n\t * The type of playback, which affects tradeoffs between audio \n\t * output latency and responsiveness. \n\t * \n\t * In addition to setting the value in seconds, the latencyHint also\n\t * accepts the strings \"interactive\" (prioritizes low latency), \n\t * \"playback\" (prioritizes sustained playback), \"balanced\" (balances\n\t * latency and performance), and \"fastest\" (lowest latency, might glitch more often). \n\t * @type {String|Seconds}\n\t * @memberOf Tone.Context#\n\t * @name latencyHint\n\t * @static\n\t * @example\n\t * //set the lookAhead to 0.3 seconds\n\t * Tone.context.latencyHint = 0.3;\n\t */\n\tObject.defineProperty(Tone.Context.prototype, \"latencyHint\", {\n\t\tget : function(){\n\t\t\treturn this._latencyHint;\n\t\t},\n\t\tset : function(hint){\n\t\t\tvar lookAhead = hint;\n\t\t\tthis._latencyHint = hint;\n\t\t\tif (this.isString(hint)){\n\t\t\t\tswitch(hint){\n\t\t\t\t\tcase \"interactive\" :\n\t\t\t\t\t\tlookAhead = 0.1;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"playback\" :\n\t\t\t\t\t\tlookAhead = 0.8;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"balanced\" :\n\t\t\t\t\t\tlookAhead = 0.25;\n\t\t\t\t\t\tthis._context.latencyHint = hint;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"fastest\" :\n\t\t\t\t\t\tlookAhead = 0.01;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.lookAhead = lookAhead;\n\t\t\tthis.updateInterval = lookAhead/3;\n\t\t}\n\t});\n\n\t/**\n\t * Shim all connect/disconnect and some deprecated methods which are still in\n\t * some older implementations.\n\t * @private\n\t */\n\tfunction shimConnect(){\n\n\t\tvar nativeConnect = AudioNode.prototype.connect;\n\t\tvar nativeDisconnect = AudioNode.prototype.disconnect;\n\n\t\t//replace the old connect method\n\t\tfunction toneConnect(B, outNum, inNum){\n\t\t\tif (B.input){\n\t\t\t\tif (Array.isArray(B.input)){\n\t\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\t\tinNum = 0;\n\t\t\t\t\t}\n\t\t\t\t\tthis.connect(B.input[inNum]);\n\t\t\t\t} else {\n\t\t\t\t\tthis.connect(B.input, outNum, inNum);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (B instanceof AudioNode){\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum, inNum);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnativeConnect.call(this, B, outNum);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error connecting to node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//replace the old disconnect method\n\t\tfunction toneDisconnect(B, outNum, inNum){\n\t\t\tif (B && B.input && Array.isArray(B.input)){\n\t\t\t\tif (Tone.prototype.isUndef(inNum)){\n\t\t\t\t\tinNum = 0;\n\t\t\t\t}\n\t\t\t\tthis.disconnect(B.input[inNum], outNum, inNum);\n\t\t\t} else if (B && B.input){\n\t\t\t\tthis.disconnect(B.input, outNum, inNum);\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tnativeDisconnect.apply(this, arguments);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(\"error disconnecting node: \"+B+\"\\n\"+e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (AudioNode.prototype.connect !== toneConnect){\n\t\t\tAudioNode.prototype.connect = toneConnect;\n\t\t\tAudioNode.prototype.disconnect = toneDisconnect;\n\t\t}\n\t}\n\n\t// set the audio context initially\n\tif (Tone.supported){\n\t\tshimConnect();\n\t\tTone.context = new Tone.Context();\n\t} else {\n\t\tconsole.warn(\"This browser does not support Tone.js\");\n\t}\n\n\treturn Tone.Context;\n});","'use strict';\n\ndefine(function () {\n /*\n Helper function to generate an error\n with a custom stack trace that points to the sketch\n and removes other parts of the stack trace.\n\n @private\n @class customError\n @constructor\n @param {String} name custom error name\n @param {String} errorTrace custom error trace\n @param {String} failedPath path to the file that failed to load\n @property {String} name custom error name\n @property {String} message custom error message\n @property {String} stack trace the error back to a line in the user's sketch.\n Note: this edits out stack trace within p5.js and p5.sound.\n @property {String} originalStack unedited, original stack trace\n @property {String} failedPath path to the file that failed to load\n @return {Error} returns a custom Error object\n */\n var CustomError = function (name, errorTrace, failedPath) {\n var err = new Error();\n var tempStack, splitStack;\n\n err.name = name;\n err.originalStack = err.stack + errorTrace;\n tempStack = err.stack + errorTrace;\n err.failedPath = failedPath;\n\n // only print the part of the stack trace that refers to the user code:\n splitStack = tempStack.split('\\n').filter(function (ln) {\n return !ln.match(/(p5.|native code|globalInit)/g);\n });\n err.stack = splitStack.join('\\n');\n\n return err; // TODO: is this really a constructor?\n };\n\n return CustomError;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\t\n\t/**\n\t * @class Performs a linear scaling on an input signal.\n\t * Scales a NormalRange input to between\n\t * outputMin and outputMax.\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {number} [outputMin=0] The output value when the input is 0. \n\t * @param {number} [outputMax=1]\tThe output value when the input is 1. \n\t * @example\n\t * var scale = new Tone.Scale(50, 100);\n\t * var signal = new Tone.Signal(0.5).connect(scale);\n\t * //the output of scale equals 75\n\t */\n\tTone.Scale = function(outputMin, outputMax){\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMin = this.defaultArg(outputMin, 0);\n\n\t\t/** \n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._outputMax = this.defaultArg(outputMax, 1);\n\n\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(1);\n\t\t\n\t\t/** \n\t\t * @private\n\t\t * @type {Tone.Add}\n\t\t * @private\n\t\t */\n\t\tthis._add = this.output = new Tone.Add(0);\n\n\t\tthis._scale.connect(this._add);\n\t\tthis._setRange();\n\t};\n\n\tTone.extend(Tone.Scale, Tone.SignalBase);\n\n\t/**\n\t * The minimum output value. This number is output when \n\t * the value input value is 0. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name min\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"min\", {\n\t\tget : function(){\n\t\t\treturn this._outputMin;\n\t\t},\n\t\tset : function(min){\n\t\t\tthis._outputMin = min;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * The maximum output value. This number is output when \n\t * the value input value is 1. \n\t * @memberOf Tone.Scale#\n\t * @type {number}\n\t * @name max\n\t */\n\tObject.defineProperty(Tone.Scale.prototype, \"max\", {\n\t\tget : function(){\n\t\t\treturn this._outputMax;\n\t\t},\n\t\tset : function(max){\n\t\t\tthis._outputMax = max;\n\t\t\tthis._setRange();\n\t\t}\n\t});\n\n\t/**\n\t * set the values\n\t * @private\n\t */\n\tTone.Scale.prototype._setRange = function() {\n\t\tthis._add.value = this._outputMin;\n\t\tthis._scale.value = this._outputMax - this._outputMin;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Scale} this\n\t */\n\tTone.Scale.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._add.dispose();\n\t\tthis._add = null;\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/core/Timeline\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A signal which adds the method getValueAtTime. \n\t * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline\n\t * @extends {Tone.Param}\n\t * @param {Number=} value The initial value of the signal\n\t * @param {String=} units The conversion units of the signal.\n\t */\n\tTone.TimelineSignal = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"value\", \"units\"], Tone.Signal.defaults);\n\t\t\n\t\t/**\n\t\t * The scheduled events\n\t\t * @type {Tone.Timeline}\n\t\t * @private\n\t\t */\n\t\tthis._events = new Tone.Timeline(10);\n\n\t\t//constructors\n\t\tTone.Signal.apply(this, options);\n\t\toptions.param = this._param;\n\t\tTone.Param.call(this, options);\n\n\t\t/**\n\t\t * The initial scheduled value\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._initial = this._fromUnits(this._param.value);\n\t};\n\n\tTone.extend(Tone.TimelineSignal, Tone.Param);\n\n\t/**\n\t * The event types of a schedulable signal.\n\t * @enum {String}\n\t * @private\n\t */\n\tTone.TimelineSignal.Type = {\n\t\tLinear : \"linear\",\n\t\tExponential : \"exponential\",\n\t\tTarget : \"target\",\n\t\tCurve : \"curve\",\n\t\tSet : \"set\"\n\t};\n\n\t/**\n\t * The current value of the signal. \n\t * @memberOf Tone.TimelineSignal#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.TimelineSignal.prototype, \"value\", {\n\t\tget : function(){\n\t\t\tvar now = this.now();\n\t\t\tvar val = this.getValueAtTime(now);\n\t\t\treturn this._toUnits(val);\n\t\t},\n\t\tset : function(value){\n\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\tthis._initial = convertedVal;\n\t\t\tthis.cancelScheduledValues();\n\t\t\tthis._param.value = convertedVal;\n\t\t}\n\t});\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tSCHEDULING\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.TimelineSignal} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Set,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime\n\t\t});\n\t\t//invoke the original event\n\t\tthis._param.setValueAtTime(value, startTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) {\n\t\tvalue = this._fromUnits(value);\n\t\tendTime = this.toSeconds(endTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Linear,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\tthis._param.linearRampToValueAtTime(value, endTime);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n\t\t//get the previous event and make sure it's not starting from 0\n\t\tendTime = this.toSeconds(endTime);\n\t\tvar beforeEvent = this._searchBefore(endTime);\n\t\tif (beforeEvent && beforeEvent.value === 0){\n\t\t\t//reschedule that event\n\t\t\tthis.setValueAtTime(this._minOutput, beforeEvent.time);\n\t\t}\n\t\tvalue = this._fromUnits(value);\n\t\tvar setValue = Math.max(value, this._minOutput);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Exponential,\n\t\t\t\"value\" : setValue,\n\t\t\t\"time\" : endTime\n\t\t});\n\t\t//if the ramped to value is 0, make it go to the min output, and then set to 0.\n\t\tif (value < this._minOutput){\n\t\t\tthis._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime);\n\t\t\tthis.setValueAtTime(0, endTime);\n\t\t} else {\n\t\t\tthis._param.exponentialRampToValueAtTime(value, endTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Target,\n\t\t\t\"value\" : value,\n\t\t\t\"time\" : startTime,\n\t\t\t\"constant\" : timeConstant\n\t\t});\n\t\tthis._param.setTargetAtTime(value, startTime, timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Set an array of arbitrary values starting at the given time for the given duration.\n\t * @param {Float32Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration\n\t * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value\n\t * @returns {Tone.TimelineSignal} this \n\t */\n\tTone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) {\n\t\tscaling = this.defaultArg(scaling, 1);\n\t\t//copy the array\n\t\tvar floats = new Array(values.length);\n\t\tfor (var i = 0; i < floats.length; i++){\n\t\t\tfloats[i] = this._fromUnits(values[i]) * scaling;\n\t\t}\n\t\tstartTime = this.toSeconds(startTime);\n\t\tduration = this.toSeconds(duration);\n\t\tthis._events.add({\n\t\t\t\"type\" : Tone.TimelineSignal.Type.Curve,\n\t\t\t\"value\" : floats,\n\t\t\t\"time\" : startTime,\n\t\t\t\"duration\" : duration\n\t\t});\n\t\t//set the first value\n\t\tthis._param.setValueAtTime(floats[0], startTime);\n\t\t//schedule a lienar ramp for each of the segments\n\t\tfor (var j = 1; j < floats.length; j++){\n\t\t\tvar segmentTime = startTime + (j / (floats.length - 1) * duration);\n\t\t\tthis._param.linearRampToValueAtTime(floats[j], segmentTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.cancelScheduledValues = function (after) {\n\t\tafter = this.toSeconds(after);\n\t\tthis._events.cancel(after);\n\t\tthis._param.cancelScheduledValues(after);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets the computed value at the given time. This provides\n\t * a point from which a linear or exponential curve\n\t * can be scheduled after. Will cancel events after \n\t * the given time and shorten the currently scheduled\n\t * linear or exponential ramp so that it ends at `time` .\n\t * This is to avoid discontinuities and clicks in envelopes. \n\t * @param {Time} time When to set the ramp point\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.setRampPoint = function (time) {\n\t\ttime = this.toSeconds(time);\n\t\t//get the value at the given time\n\t\tvar val = this._toUnits(this.getValueAtTime(time));\n\t\t//if there is an event at the given time\n\t\t//and that even is not a \"set\"\n\t\tvar before = this._searchBefore(time);\n\t\tif (before && before.time === time){\n\t\t\t//remove everything after\n\t\t\tthis.cancelScheduledValues(time + this.sampleTime);\n\t\t} else if (before && \n\t\t\t\t before.type === Tone.TimelineSignal.Type.Curve &&\n\t\t\t\t before.time + before.duration > time){\n\t\t\t//if the curve is still playing\n\t\t\t//cancel the curve\n\t\t\tthis.cancelScheduledValues(time);\n\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t} else {\n\t\t\t//reschedule the next event to end at the given time\n\t\t\tvar after = this._searchAfter(time);\n\t\t\tif (after){\n\t\t\t\t//cancel the next event(s)\n\t\t\t\tthis.cancelScheduledValues(time);\n\t\t\t\tif (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\t\t\tthis.linearRampToValueAtTime(val, time);\n\t\t\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\t\t\tthis.exponentialRampToValueAtTime(val, time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.setValueAtTime(val, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a linear ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the linear ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.linearRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Do a exponential ramp to the given value between the start and finish times.\n\t * @param {Number} value The value to ramp to.\n\t * @param {Time} start The beginning anchor point to do the exponential ramp\n\t * @param {Time} finish The ending anchor point by which the value of\n\t * the signal will equal the given value.\n\t * @returns {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) {\n\t\tthis.setRampPoint(start);\n\t\tthis.exponentialRampToValueAtTime(value, finish);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tGETTING SCHEDULED VALUES\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value before or equal to the given time\n\t * @param {Number} time The time to query\n\t * @return {Object} The event at or before the given time.\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchBefore = function(time){\n\t\treturn this._events.get(time);\n\t};\n\n\t/**\n\t * The event after the given time\n\t * @param {Number} time The time to query.\n\t * @return {Object} The next event after the given time\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._searchAfter = function(time){\n\t\treturn this._events.getAfter(time);\n\t};\n\n\t/**\n\t * Get the scheduled value at the given time. This will\n\t * return the unconverted (raw) value.\n\t * @param {Number} time The time in seconds.\n\t * @return {Number} The scheduled value at the given time.\n\t */\n\tTone.TimelineSignal.prototype.getValueAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tvar after = this._searchAfter(time);\n\t\tvar before = this._searchBefore(time);\n\t\tvar value = this._initial;\n\t\t//if it was set by\n\t\tif (before === null){\n\t\t\tvalue = this._initial;\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Target){\n\t\t\tvar previous = this._events.getBefore(before.time);\n\t\t\tvar previouVal;\n\t\t\tif (previous === null){\n\t\t\t\tpreviouVal = this._initial;\n\t\t\t} else {\n\t\t\t\tpreviouVal = previous.value;\n\t\t\t}\n\t\t\tvalue = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time);\n\t\t} else if (before.type === Tone.TimelineSignal.Type.Curve){\n\t\t\tvalue = this._curveInterpolate(before.time, before.value, before.duration, time);\n\t\t} else if (after === null){\n\t\t\tvalue = before.value;\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Linear){\n\t\t\tvalue = this._linearInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else if (after.type === Tone.TimelineSignal.Type.Exponential){\n\t\t\tvalue = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time);\n\t\t} else {\n\t\t\tvalue = before.value;\n\t\t}\n\t\treturn value;\n\t};\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.TimelineSignal} this\n\t * @method\n\t */\n\tTone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect;\n\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUTOMATION CURVE CALCULATIONS\n\t//\tMIT License, copyright (c) 2014 Jordan Santell\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Calculates the the value along the curve produced by setTargetAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) {\n\t\treturn v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by linearRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) {\n\t\treturn v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by exponentialRampToValueAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) {\n\t\tv0 = Math.max(this._minOutput, v0);\n\t\treturn v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n\t};\n\n\t/**\n\t * Calculates the the value along the curve produced by setValueCurveAtTime\n\t * @private\n\t */\n\tTone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) {\n\t\tvar len = curve.length;\n\t\t// If time is after duration, return the last curve value\n\t\tif (time >= start + duration) {\n\t\t\treturn curve[len - 1];\n\t\t} else if (time <= start){\n\t\t\treturn curve[0];\n\t\t} else {\n\t\t\tvar progress = (time - start) / duration;\n\t\t\tvar lowerIndex = Math.floor((len - 1) * progress);\n\t\t\tvar upperIndex = Math.ceil((len - 1) * progress);\n\t\t\tvar lowerVal = curve[lowerIndex];\n\t\t\tvar upperVal = curve[upperIndex];\n\t\t\tif (upperIndex === lowerIndex){\n\t\t\t\treturn lowerVal;\n\t\t\t} else {\n\t\t\t\treturn this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.TimelineSignal} this\n\t */\n\tTone.TimelineSignal.prototype.dispose = function(){\n\t\tTone.Signal.prototype.dispose.call(this);\n\t\tTone.Param.prototype.dispose.call(this);\n\t\tthis._events.dispose();\n\t\tthis._events = null;\n\t};\n\n\treturn Tone.TimelineSignal;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n *

A p5.Filter uses a Web Audio Biquad Filter to filter\n * the frequency response of an input source. Subclasses\n * include:

\n * p5.LowPass:\n * Allows frequencies below the cutoff frequency to pass through,\n * and attenuates frequencies above the cutoff.
\n * p5.HighPass:\n * The opposite of a lowpass filter.
\n * p5.BandPass:\n * Allows a range of frequencies to pass through and attenuates\n * the frequencies below and above this frequency range.
\n *\n * The .res() method controls either width of the\n * bandpass, or resonance of the low/highpass cutoff frequency.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Filter\n * @extends p5.Effect\n * @constructor\n * @param {String} [type] 'lowpass' (default), 'highpass', 'bandpass'\n * @example\n *
\n * let fft, noise, filter;\n *\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(makeNoise);\n * fill(255, 0, 255);\n *\n * filter = new p5.BandPass();\n * noise = new p5.Noise();\n * noise.disconnect();\n * noise.connect(filter);\n *\n * fft = new p5.FFT();\n * }\n *\n * function draw() {\n * background(220);\n *\n * // set the BandPass frequency based on mouseX\n * let freq = map(mouseX, 0, width, 20, 10000);\n * freq = constrain(freq, 0, 22050);\n * filter.freq(freq);\n * // give the filter a narrow band (lower res = wider bandpass)\n * filter.res(50);\n *\n * // draw filtered spectrum\n * let spectrum = fft.analyze();\n * noStroke();\n * for (let i = 0; i < spectrum.length; i++) {\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width/spectrum.length, h);\n * }\n * if (!noise.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n * }\n * }\n *\n * function makeNoise() {\n * // see also: `userStartAudio()`\n * noise.start();\n * noise.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * noise.amp(0, 0.2);\n * }\n *\n *
\n */\n p5.Filter = function (type) {\n Effect.call(this);\n //add extend Effect by adding a Biquad Filter\n\n /**\n * The p5.Filter is built with a\n * \n * Web Audio BiquadFilter Node.\n *\n * @property {DelayNode} biquadFilter\n */\n\n this.biquad = this.ac.createBiquadFilter();\n\n this.input.connect(this.biquad);\n\n this.biquad.connect(this.wet);\n\n if (type) {\n this.setType(type);\n }\n\n //Properties useful for the toggle method.\n this._on = true;\n this._untoggledType = this.biquad.type;\n };\n p5.Filter.prototype = Object.create(Effect.prototype);\n\n /**\n * Filter an audio signal according to a set\n * of filter parameters.\n *\n * @method process\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance/Width of the filter frequency\n * from 0.001 to 1000\n */\n p5.Filter.prototype.process = function (src, freq, res, time) {\n src.connect(this.input);\n this.set(freq, res, time);\n };\n\n /**\n * Set the frequency and the resonance of the filter.\n *\n * @method set\n * @param {Number} [freq] Frequency in Hz, from 10 to 22050\n * @param {Number} [res] Resonance (Q) from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Filter.prototype.set = function (freq, res, time) {\n if (freq) {\n this.freq(freq, time);\n }\n if (res) {\n this.res(res, time);\n }\n };\n\n /**\n * Set the filter frequency, in Hz, from 10 to 22050 (the range of\n * human hearing, although in reality most people hear in a narrower\n * range).\n *\n * @method freq\n * @param {Number} freq Filter Frequency\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current frequency value\n */\n p5.Filter.prototype.freq = function (freq, time) {\n var t = time || 0;\n if (freq <= 0) {\n freq = 1;\n }\n if (typeof freq === 'number') {\n this.biquad.frequency.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.biquad.frequency.exponentialRampToValueAtTime(\n freq,\n this.ac.currentTime + 0.02 + t\n );\n } else if (freq) {\n freq.connect(this.biquad.frequency);\n }\n return this.biquad.frequency.value;\n };\n\n /**\n * Controls either width of a bandpass frequency,\n * or the resonance of a low/highpass cutoff frequency.\n *\n * @method res\n * @param {Number} res Resonance/Width of filter freq\n * from 0.001 to 1000\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {Number} value Returns the current res value\n */\n p5.Filter.prototype.res = function (res, time) {\n var t = time || 0;\n if (typeof res === 'number') {\n this.biquad.Q.value = res;\n this.biquad.Q.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.Q.linearRampToValueAtTime(\n res,\n this.ac.currentTime + 0.02 + t\n );\n } else if (res) {\n res.connect(this.biquad.Q);\n }\n return this.biquad.Q.value;\n };\n\n /**\n * Controls the gain attribute of a Biquad Filter.\n * This is distinctly different from .amp() which is inherited from p5.Effect\n * .amp() controls the volume via the output gain node\n * p5.Filter.gain() controls the gain parameter of a Biquad Filter node.\n *\n * @method gain\n * @param {Number} gain\n * @return {Number} Returns the current or updated gain value\n */\n p5.Filter.prototype.gain = function (gain, time) {\n var t = time || 0;\n if (typeof gain === 'number') {\n this.biquad.gain.value = gain;\n this.biquad.gain.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.biquad.gain.linearRampToValueAtTime(\n gain,\n this.ac.currentTime + 0.02 + t\n );\n } else if (gain) {\n gain.connect(this.biquad.gain);\n }\n return this.biquad.gain.value;\n };\n\n /**\n * Toggle function. Switches between the specified type and allpass\n *\n * @method toggle\n * @return {boolean} [Toggle value]\n */\n p5.Filter.prototype.toggle = function () {\n this._on = !this._on;\n\n if (this._on === true) {\n this.biquad.type = this._untoggledType;\n } else if (this._on === false) {\n this.biquad.type = 'allpass';\n }\n\n return this._on;\n };\n\n /**\n * Set the type of a p5.Filter. Possible types include:\n * \"lowpass\" (default), \"highpass\", \"bandpass\",\n * \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n * \"allpass\".\n *\n * @method setType\n * @param {String} t\n */\n p5.Filter.prototype.setType = function (t) {\n this.biquad.type = t;\n this._untoggledType = this.biquad.type;\n };\n\n p5.Filter.prototype.dispose = function () {\n // remove reference from soundArray\n Effect.prototype.dispose.apply(this);\n if (this.biquad) {\n this.biquad.disconnect();\n delete this.biquad;\n }\n };\n\n /**\n * Constructor: new p5.LowPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('lowpass').\n * See p5.Filter for methods.\n *\n * @class p5.LowPass\n * @constructor\n * @extends p5.Filter\n */\n p5.LowPass = function () {\n p5.Filter.call(this, 'lowpass');\n };\n p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.HighPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('highpass').\n * See p5.Filter for methods.\n *\n * @class p5.HighPass\n * @constructor\n * @extends p5.Filter\n */\n p5.HighPass = function () {\n p5.Filter.call(this, 'highpass');\n };\n p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n\n /**\n * Constructor: new p5.BandPass() Filter.\n * This is the same as creating a p5.Filter and then calling\n * its method setType('bandpass').\n * See p5.Filter for methods.\n *\n * @class p5.BandPass\n * @constructor\n * @extends p5.Filter\n */\n p5.BandPass = function () {\n p5.Filter.call(this, 'bandpass');\n };\n p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n\n return p5.Filter;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Negate\", \"Tone/signal/Signal\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Subtract the signal connected to input[1] from the signal connected \n\t * to input[0]. If an argument is provided in the constructor, the \n\t * signals .value will be subtracted from the incoming signal.\n\t *\n\t * @extends {Tone.Signal}\n\t * @constructor\n\t * @param {number=} value The value to subtract from the incoming signal. If the value\n\t * is omitted, it will subtract the second signal from the first.\n\t * @example\n\t * var sub = new Tone.Subtract(1);\n\t * var sig = new Tone.Signal(4).connect(sub);\n\t * //the output of sub is 3. \n\t * @example\n\t * var sub = new Tone.Subtract();\n\t * var sigA = new Tone.Signal(10);\n\t * var sigB = new Tone.Signal(2.5);\n\t * sigA.connect(sub, 0, 0);\n\t * sigB.connect(sub, 0, 1);\n\t * //output of sub is 7.5\n\t */\n\tTone.Subtract = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\n\t\t/**\n\t\t * the summing node\n\t\t * @type {GainNode}\n\t\t * @private\n\t\t */\n\t\tthis._sum = this.input[0] = this.output = new Tone.Gain();\n\n\t\t/**\n\t\t * negate the input of the second input before connecting it\n\t\t * to the summing node.\n\t\t * @type {Tone.Negate}\n\t\t * @private\n\t\t */\n\t\tthis._neg = new Tone.Negate();\n\n\t\t/**\n\t\t * the node where the value is set\n\t\t * @private\n\t\t * @type {Tone.Signal}\n\t\t */\n\t\tthis._param = this.input[1] = new Tone.Signal(value);\n\n\t\tthis._param.chain(this._neg, this._sum);\n\t};\n\n\tTone.extend(Tone.Subtract, Tone.Signal);\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.Subtract.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._neg.dispose();\n\t\tthis._neg = null;\n\t\tthis._sum.disconnect();\n\t\tthis._sum = null;\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Subtract;\n});","'use strict';\n\nglobal.TONE_SILENCE_VERSION_LOGGING = true;\n\ndefine(['startaudiocontext', 'Tone/core/Context', 'Tone/core/Tone'], function (\n StartAudioContext,\n Context,\n Tone\n) {\n // Create the Audio Context\n const audiocontext = new window.AudioContext();\n\n // Tone and p5.sound share the same audio context\n Tone.context.dispose();\n Tone.setContext(audiocontext);\n\n /**\n *

Returns the Audio Context for this sketch. Useful for users\n * who would like to dig deeper into the Web Audio API\n * .

\n *\n *

Some browsers require users to startAudioContext\n * with a user gesture, such as touchStarted in the example below.

\n *\n * @for p5\n * @method getAudioContext\n * @return {Object} AudioContext for this sketch\n * @example\n *
\n * function draw() {\n * background(255);\n * textAlign(CENTER);\n *\n * if (getAudioContext().state !== 'running') {\n * text('click to start audio', width/2, height/2);\n * } else {\n * text('audio is enabled', width/2, height/2);\n * }\n * }\n *\n * function touchStarted() {\n * if (getAudioContext().state !== 'running') {\n * getAudioContext().resume();\n * }\n * var synth = new p5.MonoSynth();\n * synth.play('A4', 0.5, 0, 0.2);\n * }\n *\n *
\n */\n p5.prototype.getAudioContext = function () {\n return audiocontext;\n };\n\n /**\n *

It is not only a good practice to give users control over starting\n * audio. This policy is enforced by many web browsers, including iOS and\n * Google Chrome, which create the Web Audio API's\n * Audio Context\n * in a suspended state.

\n *\n *

In these browser-specific policies, sound will not play until a user\n * interaction event (i.e. mousePressed()) explicitly resumes\n * the AudioContext, or starts an audio node. This can be accomplished by\n * calling start() on a p5.Oscillator,\n * play() on a p5.SoundFile, or simply\n * userStartAudio().

\n *\n *

userStartAudio() starts the AudioContext on a user\n * gesture. The default behavior will enable audio on any\n * mouseUp or touchEnd event. It can also be placed in a specific\n * interaction function, such as mousePressed() as in the\n * example below. This method utilizes\n * StartAudioContext\n * , a library by Yotam Mann (MIT Licence, 2016).

\n * @param {Element|Array} [element(s)] This argument can be an Element,\n * Selector String, NodeList, p5.Element,\n * jQuery Element, or an Array of any of those.\n * @param {Function} [callback] Callback to invoke when the AudioContext\n * has started\n * @return {Promise} Returns a Promise that resolves when\n * the AudioContext state is 'running'\n * @method userStartAudio\n * @for p5\n * @example\n *
\n * function setup() {\n * // mimics the autoplay policy\n * getAudioContext().suspend();\n *\n * let mySynth = new p5.MonoSynth();\n *\n * // This won't play until the context has resumed\n * mySynth.play('A6');\n * }\n * function draw() {\n * background(220);\n * textAlign(CENTER, CENTER);\n * text(getAudioContext().state, width/2, height/2);\n * }\n * function mousePressed() {\n * userStartAudio();\n * }\n *
\n */\n p5.prototype.userStartAudio = function (elements, callback) {\n var elt = elements;\n if (elements instanceof p5.Element) {\n elt = elements.elt;\n } else if (elements instanceof Array && elements[0] instanceof p5.Element) {\n elt = elements.map(function (e) {\n return e.elt;\n });\n }\n return StartAudioContext(audiocontext, elt, callback);\n };\n\n return audiocontext;\n});\n","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Emitter gives classes which extend it\n\t * the ability to listen for and emit events. \n\t * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n\t * MIT (c) 2011 Jerome Etienne.\n\t * \n\t * @extends {Tone}\n\t */\n\tTone.Emitter = function(){\n\t\t/**\n\t\t * Contains all of the events.\n\t\t * @private\n\t\t * @type {Object}\n\t\t */\n\t\tthis._events = {};\n\t};\n\n\tTone.extend(Tone.Emitter);\n\n\t/**\n\t * Bind a callback to a specific event.\n\t * @param {String} event The name of the event to listen for.\n\t * @param {Function} callback The callback to invoke when the\n\t * event is emitted\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.on = function(event, callback){\n\t\t//split the event\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var i = 0; i < events.length; i++){\n\t\t\tvar eventName = events[i];\n\t\t\tif (!this._events.hasOwnProperty(eventName)){\n\t\t\t\tthis._events[eventName] = [];\n\t\t\t}\n\t\t\tthis._events[eventName].push(callback);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove the event listener.\n\t * @param {String} event The event to stop listening to.\n\t * @param {Function=} callback The callback which was bound to \n\t * the event with Tone.Emitter.on.\n\t * If no callback is given, all callbacks\n\t * events are removed.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.off = function(event, callback){\n\t\tvar events = event.split(/\\W+/);\n\t\tfor (var ev = 0; ev < events.length; ev++){\n\t\t\tevent = events[ev];\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tif (Tone.prototype.isUndef(callback)){\n\t\t\t\t\tthis._events[event] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar eventList = this._events[event];\n\t\t\t\t\tfor (var i = 0; i < eventList.length; i++){\n\t\t\t\t\t\tif (eventList[i] === callback){\n\t\t\t\t\t\t\teventList.splice(i, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Invoke all of the callbacks bound to the event\n\t * with any arguments passed in. \n\t * @param {String} event The name of the event.\n\t * @param {*...} args The arguments to pass to the functions listening.\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.emit = function(event){\n\t\tif (this._events){\n\t\t\tvar args = Array.apply(null, arguments).slice(1);\n\t\t\tif (this._events.hasOwnProperty(event)){\n\t\t\t\tvar eventList = this._events[event];\n\t\t\t\tfor (var i = 0, len = eventList.length; i < len; i++){\n\t\t\t\t\teventList[i].apply(this, args);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add Emitter functions (on/off/emit) to the object\n\t * @param {Object|Function} object The object or class to extend.\n\t */\n\tTone.Emitter.mixin = function(object){\n\t\tvar functions = [\"on\", \"off\", \"emit\"];\n\t\tobject._events = {};\n\t\tfor (var i = 0; i < functions.length; i++){\n\t\t\tvar func = functions[i];\n\t\t\tvar emitterFunc = Tone.Emitter.prototype[func];\n\t\t\tobject[func] = emitterFunc;\n\t\t}\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.Emitter} this\n\t */\n\tTone.Emitter.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._events = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Emitter;\n});","define([\"Tone/core/Tone\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Base class for all Signals. Used Internally. \n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t */\n\tTone.SignalBase = function(){};\n\n\tTone.extend(Tone.SignalBase);\n\n\t/**\n\t * When signals connect to other signals or AudioParams, \n\t * they take over the output value of that signal or AudioParam. \n\t * For all other nodes, the behavior is the same as a default connect. \n\t *\n\t * @override\n\t * @param {AudioParam|AudioNode|Tone.Signal|Tone} node \n\t * @param {number} [outputNumber=0] The output number to connect from.\n\t * @param {number} [inputNumber=0] The input number to connect to.\n\t * @returns {Tone.SignalBase} this\n\t */\n\tTone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){\n\t\t//zero it out so that the signal can have full control\n\t\tif ((Tone.Signal && Tone.Signal === node.constructor) || \n\t\t\t\t(Tone.Param && Tone.Param === node.constructor) || \n\t\t\t\t(Tone.TimelineSignal && Tone.TimelineSignal === node.constructor)){\n\t\t\t//cancel changes\n\t\t\tnode._param.cancelScheduledValues(0);\n\t\t\t//reset the value\n\t\t\tnode._param.value = 0;\n\t\t\t//mark the value as overridden\n\t\t\tnode.overridden = true;\n\t\t} else if (node instanceof AudioParam){\n\t\t\tnode.cancelScheduledValues(0);\n\t\t\tnode.value = 0;\n\t\t} \n\t\tTone.prototype.connect.call(this, node, outputNumber, inputNumber);\n\t\treturn this;\n\t};\n\n\treturn Tone.SignalBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Time is a primitive type for encoding Time values. \n\t * Eventually all time values are evaluated to seconds\n\t * using the `eval` method. Tone.Time can be constructed\n\t * with or without the `new` keyword. Tone.Time can be passed\n\t * into the parameter of any method which takes time as an argument. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * var t = Tone.Time(\"4n\");//encodes a quarter note\n\t * t.mult(4); // multiply that value by 4\n\t * t.toNotation(); //returns \"1m\"\n\t */\n\tTone.Time = function(val, units){\n\t\tif (this instanceof Tone.Time){\n\n\t\t\t/**\n\t\t\t * If the current clock time should\n\t\t\t * be added to the output\n\t\t\t * @type {Boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._plusNow = false;\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Time(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Time, Tone.TimeBase);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions);\n\n\t/*\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\treturn Tone.Transport.nextSubdivision(rh());\n\t\t}\n\t};\n\n\t/*\n\t * Adds an additional unary expression\n\t * which adds the current clock time.\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Time.prototype._unaryExpressions.now = {\n\t\tregexp : /^\\+/,\n\t\tmethod : function(lh){\n\t\t\tthis._plusNow = true;\n\t\t\treturn lh();\n\t\t}\n\t};\n\n\t/**\n\t * Quantize the time by the given subdivision. Optionally add a\n\t * percentage which will move the time value towards the ideal\n\t * quantized value by that percentage. \n\t * @param {Number|Time} val The subdivision to quantize to\n\t * @param {NormalRange} [percent=1] Move the time value\n\t * towards the quantized value by\n\t * a percentage.\n\t * @return {Tone.Time} this\n\t * @example\n\t * Tone.Time(21).quantize(2) //returns 22\n\t * Tone.Time(0.6).quantize(\"4n\", 0.5) //returns 0.55\n\t */\n\tTone.Time.prototype.quantize = function(subdiv, percent){\n\t\tpercent = this.defaultArg(percent, 1);\n\t\tthis._expr = function(expr, subdivision, percent){\n\t\t\texpr = expr();\n\t\t\tsubdivision = subdivision.toSeconds();\n\t\t\tvar multiple = Math.round(expr / subdivision);\n\t\t\tvar ideal = multiple * subdivision;\n\t\t\tvar diff = ideal - expr;\n\t\t\treturn expr + diff * percent;\n\t\t}.bind(this, this._expr, new this.constructor(subdiv), percent);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Adds the clock time to the time expression at the \n\t * moment of evaluation. \n\t * @return {Tone.Time} this\n\t */\n\tTone.Time.prototype.addNow = function(){\n\t\tthis._plusNow = true;\n\t\treturn this;\n\t};\n\n\t/**\n\t * @override\n\t * Override the default value return when no arguments are passed in.\n\t * The default value is 'now'\n\t * @private\n\t */\n\tTone.Time.prototype._defaultExpr = function(){\n\t\tthis._plusNow = true;\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.Time} time\n\t * @return {Time}\n\t */\n\tTone.Time.prototype.copy = function(time){\n\t\tTone.TimeBase.prototype.copy.call(this, time);\n\t\tthis._plusNow = time._plusNow;\n\t\treturn this;\n\t};\n\n\t//CONVERSIONS//////////////////////////////////////////////////////////////\n\n\t/**\n\t * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. \n\t * @return {Notation} \n\t * @example\n\t * //if the Transport is at 120bpm:\n\t * Tone.Time(2).toNotation();//returns \"1m\"\n\t */\n\tTone.Time.prototype.toNotation = function(){\n\t\tvar time = this.toSeconds();\n\t\tvar testNotations = [\"1m\", \"2n\", \"4n\", \"8n\", \"16n\", \"32n\", \"64n\", \"128n\"];\n\t\tvar retNotation = this._toNotationHelper(time, testNotations);\n\t\t//try the same thing but with tripelets\n\t\tvar testTripletNotations = [\"1m\", \"2n\", \"2t\", \"4n\", \"4t\", \"8n\", \"8t\", \"16n\", \"16t\", \"32n\", \"32t\", \"64n\", \"64t\", \"128n\"];\n\t\tvar retTripletNotation = this._toNotationHelper(time, testTripletNotations);\n\t\t//choose the simpler expression of the two\n\t\tif (retTripletNotation.split(\"+\").length < retNotation.split(\"+\").length){\n\t\t\treturn retTripletNotation;\n\t\t} else {\n\t\t\treturn retNotation;\n\t\t}\n\t};\n\n\t/**\n\t * Helper method for Tone.toNotation\n\t * @param {Number} units \n\t * @param {Array} testNotations\n\t * @return {String}\n\t * @private\n\t */\n\tTone.Time.prototype._toNotationHelper = function(units, testNotations){\n\t\t//the threshold is the last value in the array\n\t\tvar threshold = this._notationToUnits(testNotations[testNotations.length - 1]);\n\t\tvar retNotation = \"\";\n\t\tfor (var i = 0; i < testNotations.length; i++){\n\t\t\tvar notationTime = this._notationToUnits(testNotations[i]);\n\t\t\t//account for floating point errors (i.e. round up if the value is 0.999999)\n\t\t\tvar multiple = units / notationTime;\n\t\t\tvar floatingPointError = 0.000001;\n\t\t\tif (1 - multiple % 1 < floatingPointError){\n\t\t\t\tmultiple += floatingPointError;\n\t\t\t}\n\t\t\tmultiple = Math.floor(multiple);\n\t\t\tif (multiple > 0){\n\t\t\t\tif (multiple === 1){\n\t\t\t\t\tretNotation += testNotations[i];\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += multiple.toString() + \"*\" + testNotations[i];\n\t\t\t\t}\n\t\t\t\tunits -= multiple * notationTime;\n\t\t\t\tif (units < threshold){\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretNotation += \" + \";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (retNotation === \"\"){\n\t\t\tretNotation = \"0\";\n\t\t}\n\t\treturn retNotation;\n\t};\n\n\t/**\n\t * Convert a notation value to the current units\n\t * @param {Notation} notation \n\t * @return {Number} \n\t * @private\n\t */\n\tTone.Time.prototype._notationToUnits = function(notation){\n\t\tvar primaryExprs = this._primaryExpressions;\n\t\tvar notationExprs = [primaryExprs.n, primaryExprs.t, primaryExprs.m];\n\t\tfor (var i = 0; i < notationExprs.length; i++){\n\t\t\tvar expr = notationExprs[i];\n\t\t\tvar match = notation.match(expr.regexp);\n\t\t\tif (match){\n\t\t\t\treturn expr.method.call(this, match[1]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Return the time encoded as Bars:Beats:Sixteenths.\n\t * @return {BarsBeatsSixteenths}\n\t */\n\tTone.Time.prototype.toBarsBeatsSixteenths = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.toSeconds() / quarterTime;\n\t\tvar measures = Math.floor(quarters / this._timeSignature());\n\t\tvar sixteenths = (quarters % 1) * 4;\n\t\tquarters = Math.floor(quarters) % this._timeSignature();\n\t\tsixteenths = sixteenths.toString();\n\t\tif (sixteenths.length > 3){\n\t\t\tsixteenths = parseFloat(sixteenths).toFixed(3);\n\t\t}\n\t\tvar progress = [measures, quarters, sixteenths];\n\t\treturn progress.join(\":\");\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.Time.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time in samples\n\t * @return {Samples} \n\t */\n\tTone.Time.prototype.toSamples = function(){\n\t\treturn this.toSeconds() * this.context.sampleRate;\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t * @example\n\t * Tone.Time(2).toFrequency(); //0.5\n\t */\n\tTone.Time.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.toSeconds = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in milliseconds.\n\t * @return {Milliseconds} \n\t */\n\tTone.Time.prototype.toMilliseconds = function(){\n\t\treturn this.toSeconds() * 1000;\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.Time.prototype.valueOf = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow?this.now():0);\n\t};\n\n\treturn Tone.Time;\n});","define([\"Tone/core/Tone\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TimeBase is a flexible encoding of time\n\t * which can be evaluated to and from a string.\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t * @extends {Tone}\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @example\n\t * Tone.TimeBase(4, \"n\")\n\t * Tone.TimeBase(2, \"t\")\n\t * Tone.TimeBase(\"2t\").add(\"1m\")\n\t * Tone.TimeBase(\"2t + 1m\");\n\t */\n\tTone.TimeBase = function(val, units){\n\n\t\t//allows it to be constructed with or without 'new'\n\t\tif (this instanceof Tone.TimeBase) {\n\n\t\t\t/**\n\t\t\t * Any expressions parsed from the Time\n\t\t\t * @type {Array}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._expr = this._noOp;\n\n\t\t\tif (val instanceof Tone.TimeBase){\n\t\t\t\tthis.copy(val);\n\t\t\t} else if (!this.isUndef(units) || this.isNumber(val)){\n\t\t\t\t//default units\n\t\t\t\tunits = this.defaultArg(units, this._defaultUnits);\n\t\t\t\tvar method = this._primaryExpressions[units].method;\n\t\t\t\tthis._expr = method.bind(this, val);\n\t\t\t} else if (this.isString(val)){\n\t\t\t\tthis.set(val);\n\t\t\t} else if (this.isUndef(val)){\n\t\t\t\t//default expression\n\t\t\t\tthis._expr = this._defaultExpr();\n\t\t\t}\n\t\t} else {\n\n\t\t\treturn new Tone.TimeBase(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TimeBase);\n\n\t/**\n\t * Repalce the current time value with the value\n\t * given by the expression string.\n\t * @param {String} exprString\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.set = function(exprString){\n\t\tthis._expr = this._parseExprString(exprString);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Return a clone of the TimeBase object.\n\t * @return {Tone.TimeBase} The new cloned Tone.TimeBase\n\t */\n\tTone.TimeBase.prototype.clone = function(){\n\t\tvar instance = new this.constructor();\n\t\tinstance.copy(this);\n\t\treturn instance;\n\t};\n\n\t/**\n\t * Copies the value of time to this Time\n\t * @param {Tone.TimeBase} time\n\t * @return {TimeBase}\n\t */\n\tTone.TimeBase.prototype.copy = function(time){\n\t\tvar val = time._expr();\n\t\treturn this.set(val);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tABSTRACT SYNTAX TREE PARSER\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * All the primary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._primaryExpressions = {\n\t\t\"n\" : {\n\t\t\tregexp : /^(\\d+)n/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\tif (value === 1){\n\t\t\t\t\treturn this._beatsToUnits(this._timeSignature());\n\t\t\t\t} else {\n\t\t\t\t\treturn this._beatsToUnits(4 / value);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t\"t\" : {\n\t\t\tregexp : /^(\\d+)t/i,\n\t\t\tmethod : function(value){\n\t\t\t\tvalue = parseInt(value);\n\t\t\t\treturn this._beatsToUnits(8 / (parseInt(value) * 3));\n\t\t\t}\n\t\t},\n\t\t\"m\" : {\n\t\t\tregexp : /^(\\d+)m/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._beatsToUnits(parseInt(value) * this._timeSignature());\n\t\t\t}\n\t\t},\n\t\t\"i\" : {\n\t\t\tregexp : /^(\\d+)i/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._ticksToUnits(parseInt(value));\n\t\t\t}\n\t\t},\n\t\t\"hz\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)hz/i,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._frequencyToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"tr\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\t\tvar total = 0;\n\t\t\t\tif (m && m !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t\t}\n\t\t\t\tif (q && q !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(q));\n\t\t\t\t}\n\t\t\t\tif (s && s !== \"0\"){\n\t\t\t\t\ttotal += this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t\t}\n\t\t\t\treturn total;\n\t\t\t}\n\t\t},\n\t\t\"s\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?s)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._secondsToUnits(parseFloat(value));\n\t\t\t}\n\t\t},\n\t\t\"samples\" : {\n\t\t\tregexp : /^(\\d+)samples/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn parseInt(value) / this.context.sampleRate;\n\t\t\t}\n\t\t},\n\t\t\"default\" : {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?)/,\n\t\t\tmethod : function(value){\n\t\t\t\treturn this._primaryExpressions[this._defaultUnits].method.call(this, value);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the binary expressions that TimeBase can accept.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._binaryExpressions = {\n\t\t\"+\" : {\n\t\t\tregexp : /^\\+/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() + rh();\n\t\t\t}\n\t\t},\n\t\t\"-\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tprecedence : 2,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() - rh();\n\t\t\t}\n\t\t},\n\t\t\"*\" : {\n\t\t\tregexp : /^\\*/,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() * rh();\n\t\t\t}\n\t\t},\n\t\t\"/\" : {\n\t\t\tregexp : /^\\//,\n\t\t\tprecedence : 1,\n\t\t\tmethod : function(lh, rh){\n\t\t\t\treturn lh() / rh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * All the unary expressions.\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._unaryExpressions = {\n\t\t\"neg\" : {\n\t\t\tregexp : /^\\-/,\n\t\t\tmethod : function(lh){\n\t\t\t\treturn -lh();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Syntactic glue which holds expressions together\n\t * @private\n\t * @type {Object}\n\t */\n\tTone.TimeBase.prototype._syntaxGlue = {\n\t\t\"(\" : {\n\t\t\tregexp : /^\\(/\n\t\t},\n\t\t\")\" : {\n\t\t\tregexp : /^\\)/\n\t\t}\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.TimeBase.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr, this);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr, context){\n\t\t\tvar expressions = [\"_binaryExpressions\", \"_unaryExpressions\", \"_primaryExpressions\", \"_syntaxGlue\"];\n\t\t\tfor (var i = 0; i < expressions.length; i++){\n\t\t\t\tvar group = context[expressions[i]];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmethod : op.method,\n\t\t\t\t\t\t\tprecedence : op.precedence,\n\t\t\t\t\t\t\tregexp : op.regexp,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * Given a token, find the value within the groupName\n\t * @param {Object} token\n\t * @param {String} groupName\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._matchGroup = function(token, group, prec) {\n\t\tvar ret = false;\n\t\tif (!this.isUndef(token)){\n\t\t\tfor (var opName in group){\n\t\t\t\tvar op = group[opName];\n\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\tif (!this.isUndef(prec)){\n\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\treturn op;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn op;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * Match a binary expression given the token and the precedence\n\t * @param {Lexer} lexer\n\t * @param {Number} precedence\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseBinary = function(lexer, precedence){\n\t\tif (this.isUndef(precedence)){\n\t\t\tprecedence = 2;\n\t\t}\n\t\tvar expr;\n\t\tif (precedence < 0){\n\t\t\texpr = this._parseUnary(lexer);\n\t\t} else {\n\t\t\texpr = this._parseBinary(lexer, precedence - 1);\n\t\t}\n\t\tvar token = lexer.peek();\n\t\twhile (token && this._matchGroup(token, this._binaryExpressions, precedence)){\n\t\t\ttoken = lexer.next();\n\t\t\texpr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1));\n\t\t\ttoken = lexer.peek();\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * Match a unary expression.\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseUnary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tvar op = this._matchGroup(token, this._unaryExpressions);\n\t\tif (op) {\n\t\t\ttoken = lexer.next();\n\t\t\texpr = this._parseUnary(lexer);\n\t\t\treturn op.method.bind(this, expr);\n\t\t}\n\t\treturn this._parsePrimary(lexer);\n\t};\n\n\t/**\n\t * Match a primary expression (a value).\n\t * @param {Lexer} lexer\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parsePrimary = function(lexer){\n\t\tvar token, expr;\n\t\ttoken = lexer.peek();\n\t\tif (this.isUndef(token)) {\n\t\t\tthrow new SyntaxError(\"Tone.TimeBase: Unexpected end of expression\");\n\t\t}\n\t\tif (this._matchGroup(token, this._primaryExpressions)) {\n\t\t\ttoken = lexer.next();\n\t\t\tvar matching = token.value.match(token.regexp);\n\t\t\treturn token.method.bind(this, matching[1], matching[2], matching[3]);\n\t\t}\n\t\tif (token && token.value === \"(\"){\n\t\t\tlexer.next();\n\t\t\texpr = this._parseBinary(lexer);\n\t\t\ttoken = lexer.next();\n\t\t\tif (!(token && token.value === \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\t\tthrow new SyntaxError(\"Tone.TimeBase: Cannot process token \" + token.value);\n\t};\n\n\t/**\n\t * Recursively parse the string expression into a syntax tree.\n\t * @param {string} expr \n\t * @return {Function} the bound method to be evaluated later\n\t * @private\n\t */\n\tTone.TimeBase.prototype._parseExprString = function(exprString){\n\t\tif (!this.isString(exprString)){\n\t\t\texprString = exprString.toString();\n\t\t}\n\t\tvar lexer = this._tokenize(exprString);\n\t\tvar tree = this._parseBinary(lexer);\n\t\treturn tree;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tDEFAULTS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * The initial expression value\n\t * @return {Number} The initial value 0\n\t * @private\n\t */\n\tTone.TimeBase.prototype._noOp = function(){\n\t\treturn 0;\n\t};\n\n\t/**\n\t * The default expression value if no arguments are given\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultExpr = function(){\n\t\treturn this._noOp;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.TimeBase.prototype._defaultUnits = \"s\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._frequencyToUnits = function(freq){\n\t\treturn 1/freq;\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._beatsToUnits = function(beats){\n\t\treturn (60 / Tone.Transport.bpm.value) * beats;\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._secondsToUnits = function(seconds){\n\t\treturn seconds;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._ticksToUnits = function(ticks){\n\t\treturn ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Return the time signature.\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.TimeBase.prototype._timeSignature = function(){\n\t\treturn Tone.Transport.timeSignature;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Push an expression onto the expression list\n\t * @param {Time} val\n\t * @param {String} type\n\t * @param {String} units\n\t * @return {Tone.TimeBase} \n\t * @private\n\t */\n\tTone.TimeBase.prototype._pushExpr = function(val, name, units){\n\t\t//create the expression\n\t\tif (!(val instanceof Tone.TimeBase)){\n\t\t\tval = new this.constructor(val, units);\n\t\t}\n\t\tthis._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Add to the current value.\n\t * @param {Time} val The value to add\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").add(\"1m\"); //\"3m\"\n\t */\n\tTone.TimeBase.prototype.add = function(val, units){\n\t\treturn this._pushExpr(val, \"+\", units);\n\t};\n\n\t/**\n\t * Subtract the value from the current time.\n\t * @param {Time} val The value to subtract\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").sub(\"1m\"); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.sub = function(val, units){\n\t\treturn this._pushExpr(val, \"-\", units);\n\t};\n\n\t/**\n\t * Multiply the current value by the given time.\n\t * @param {Time} val The value to multiply\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").mult(\"2\"); //\"4m\"\n\t */\n\tTone.TimeBase.prototype.mult = function(val, units){\n\t\treturn this._pushExpr(val, \"*\", units);\n\t};\n\n\t/**\n\t * Divide the current value by the given time.\n\t * @param {Time} val The value to divide by\n\t * @param {String=} units Optional units to use with the value.\n\t * @return {Tone.TimeBase} this\n\t * @example\n\t * Tone.TimeBase(\"2m\").div(2); //\"1m\"\n\t */\n\tTone.TimeBase.prototype.div = function(val, units){\n\t\treturn this._pushExpr(val, \"/\", units);\n\t};\n\n\t/**\n\t * Evaluate the time value. Returns the time\n\t * in seconds.\n\t * @return {Seconds} \n\t */\n\tTone.TimeBase.prototype.valueOf = function(){\n\t\treturn this._expr();\n\t};\n\n\t/**\n\t * Clean up\n\t * @return {Tone.TimeBase} this\n\t */\n\tTone.TimeBase.prototype.dispose = function(){\n\t\tthis._expr = null;\n\t};\n\n\treturn Tone.TimeBase;\n});","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Param wraps the native Web Audio's AudioParam to provide\n\t * additional unit conversion functionality. It also\n\t * serves as a base-class for classes which have a single,\n\t * automatable parameter. \n\t * @extends {Tone}\n\t * @param {AudioParam} param The parameter to wrap.\n\t * @param {Tone.Type} units The units of the audio param.\n\t * @param {Boolean} convert If the param should be converted.\n\t */\n\tTone.Param = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"param\", \"units\", \"convert\"], Tone.Param.defaults);\n\n\t\t/**\n\t\t * The native parameter to control\n\t\t * @type {AudioParam}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input = options.param;\n\n\t\t/**\n\t\t * The units of the parameter\n\t\t * @type {Tone.Type}\n\t\t */\n\t\tthis.units = options.units;\n\n\t\t/**\n\t\t * If the value should be converted or not\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis.convert = options.convert;\n\n\t\t/**\n\t\t * True if the signal value is being overridden by \n\t\t * a connected signal.\n\t\t * @readOnly\n\t\t * @type {boolean}\n\t\t * @private\n\t\t */\n\t\tthis.overridden = false;\n\n\t\t/**\n\t\t * If there is an LFO, this is where it is held.\n\t\t * @type {Tone.LFO}\n\t\t * @private\n\t\t */\n\t\tthis._lfo = null;\n\n\t\tif (this.isObject(options.lfo)){\n\t\t\tthis.value = options.lfo;\n\t\t} else if (!this.isUndef(options.value)){\n\t\t\tthis.value = options.value;\n\t\t}\n\t};\n\n\tTone.extend(Tone.Param);\n\t\n\t/**\n\t * Defaults\n\t * @type {Object}\n\t * @const\n\t */\n\tTone.Param.defaults = {\n\t\t\"units\" : Tone.Type.Default,\n\t\t\"convert\" : true,\n\t\t\"param\" : undefined\n\t};\n\n\t/**\n\t * The current value of the parameter. \n\t * @memberOf Tone.Param#\n\t * @type {Number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._toUnits(this._param.value);\n\t\t},\n\t\tset : function(value){\n\t\t\tif (this.isObject(value)){\n\t\t\t\t//throw an error if the LFO needs to be included\n\t\t\t\tif (this.isUndef(Tone.LFO)){\n\t\t\t\t\tthrow new Error(\"Include 'Tone.LFO' to use an LFO as a Param value.\");\n\t\t\t\t}\n\t\t\t\t//remove the old one\n\t\t\t\tif (this._lfo){\n\t\t\t\t\tthis._lfo.dispose();\n\t\t\t\t}\n\t\t\t\tthis._lfo = new Tone.LFO(value).start();\n\t\t\t\tthis._lfo.connect(this.input);\n\t\t\t} else {\n\t\t\t\tvar convertedVal = this._fromUnits(value);\n\t\t\t\tthis._param.cancelScheduledValues(0);\n\t\t\t\tthis._param.value = convertedVal;\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * Convert the given value from the type specified by Tone.Param.units\n\t * into the destination value (such as Gain or Frequency).\n\t * @private\n\t * @param {*} val the value to convert\n\t * @return {number} the number which the value should be set to\n\t */\n\tTone.Param.prototype._fromUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Time: \n\t\t\t\t\treturn this.toSeconds(val);\n\t\t\t\tcase Tone.Type.Frequency: \n\t\t\t\t\treturn this.toFrequency(val);\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.dbToGain(val);\n\t\t\t\tcase Tone.Type.NormalRange: \n\t\t\t\t\treturn Math.min(Math.max(val, 0), 1);\n\t\t\t\tcase Tone.Type.AudioRange: \n\t\t\t\t\treturn Math.min(Math.max(val, -1), 1);\n\t\t\t\tcase Tone.Type.Positive: \n\t\t\t\t\treturn Math.max(val, 0);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * Convert the parameters value into the units specified by Tone.Param.units.\n\t * @private\n\t * @param {number} val the value to convert\n\t * @return {number}\n\t */\n\tTone.Param.prototype._toUnits = function(val){\n\t\tif (this.convert || this.isUndef(this.convert)){\n\t\t\tswitch(this.units){\n\t\t\t\tcase Tone.Type.Decibels: \n\t\t\t\t\treturn this.gainToDb(val);\n\t\t\t\tdefault:\n\t\t\t\t\treturn val;\n\t\t\t}\n\t\t} else {\n\t\t\treturn val;\n\t\t}\n\t};\n\n\t/**\n\t * the minimum output value\n\t * @type {Number}\n\t * @private\n\t */\n\tTone.Param.prototype._minOutput = 0.00001;\n\n\t/**\n\t * Schedules a parameter value change at the given time.\n\t * @param {*}\tvalue The value to set the signal.\n\t * @param {Time} time The time when the change should occur.\n\t * @returns {Tone.Param} this\n\t * @example\n\t * //set the frequency to \"G4\" in exactly 1 second from now. \n\t * freq.setValueAtTime(\"G4\", \"+1\");\n\t */\n\tTone.Param.prototype.setValueAtTime = function(value, time){\n\t\tvalue = this._fromUnits(value);\n\t\ttime = this.toSeconds(time);\n\t\tif (time <= this.now() + this.blockTime){\n\t\t\tthis._param.value = value;\n\t\t} else {\n\t\t\tthis._param.setValueAtTime(value, time);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Creates a schedule point with the current value at the current time.\n\t * This is useful for creating an automation anchor point in order to \n\t * schedule changes from the current value. \n\t *\n\t * @param {number=} now (Optionally) pass the now value in. \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setRampPoint = function(now){\n\t\tnow = this.defaultArg(now, this.now());\n\t\tvar currentVal = this._param.value;\n\t\t// exponentialRampToValueAt cannot ever ramp from or to 0\n\t\t// More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2\n\t\tif (currentVal === 0){\n\t\t\tcurrentVal = this._minOutput;\n\t\t}\n\t\tthis._param.setValueAtTime(currentVal, now);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules a linear continuous change in parameter value from the \n\t * previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.linearRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tthis._param.linearRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the previous scheduled parameter value to the given value.\n\t * \n\t * @param {number} value \n\t * @param {Time} endTime \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.exponentialRampToValueAtTime = function(value, endTime){\n\t\tvalue = this._fromUnits(value);\n\t\tvalue = Math.max(this._minOutput, value);\n\t\tthis._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an exponential continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //exponentially ramp to the value 2 over 4 seconds. \n\t * signal.exponentialRampToValue(2, 4);\n\t */\n\tTone.Param.prototype.exponentialRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Schedules an linear continuous change in parameter value from \n\t * the current time and current value to the given value over the \n\t * duration of the rampTime.\n\t * \n\t * @param {number} value The value to ramp to.\n\t * @param {Time} rampTime the time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //linearly ramp to the value 4 over 3 seconds. \n\t * signal.linearRampToValue(4, 3);\n\t */\n\tTone.Param.prototype.linearRampToValue = function(value, rampTime, startTime){\n\t\tstartTime = this.toSeconds(startTime);\n\t\tthis.setRampPoint(startTime);\n\t\tthis.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Start exponentially approaching the target value at the given time with\n\t * a rate having the given time constant.\n\t * @param {number} value \n\t * @param {Time} startTime \n\t * @param {number} timeConstant \n\t * @returns {Tone.Param} this \n\t */\n\tTone.Param.prototype.setTargetAtTime = function(value, startTime, timeConstant){\n\t\tvalue = this._fromUnits(value);\n\t\t// The value will never be able to approach without timeConstant > 0.\n\t\t// http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation\n\t\t// is described. 0 results in a division by 0.\n\t\tvalue = Math.max(this._minOutput, value);\n\t\ttimeConstant = Math.max(this._minOutput, timeConstant);\n\t\tthis._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Sets an array of arbitrary parameter values starting at the given time\n\t * for the given duration.\n\t * \t\n\t * @param {Array} values \n\t * @param {Time} startTime \n\t * @param {Time} duration \n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.setValueCurveAtTime = function(values, startTime, duration){\n\t\tfor (var i = 0; i < values.length; i++){\n\t\t\tvalues[i] = this._fromUnits(values[i]);\n\t\t}\n\t\tthis._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancels all scheduled parameter changes with times greater than or \n\t * equal to startTime.\n\t * \n\t * @param {Time} startTime\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.cancelScheduledValues = function(startTime){\n\t\tthis._param.cancelScheduledValues(this.toSeconds(startTime));\n\t\treturn this;\n\t};\n\n\t/**\n\t * Ramps to the given value over the duration of the rampTime. \n\t * Automatically selects the best ramp type (exponential or linear)\n\t * depending on the `units` of the signal\n\t * \n\t * @param {number} value \n\t * @param {Time} rampTime \tThe time that it takes the \n\t * value to ramp from it's current value\n\t * @param {Time}\t[startTime=now] \tWhen the ramp should start. \n\t * @returns {Tone.Param} this\n\t * @example\n\t * //ramp to the value either linearly or exponentially \n\t * //depending on the \"units\" value of the signal\n\t * signal.rampTo(0, 10);\n\t * @example\n\t * //schedule it to ramp starting at a specific time\n\t * signal.rampTo(0, 10, 5)\n\t */\n\tTone.Param.prototype.rampTo = function(value, rampTime, startTime){\n\t\trampTime = this.defaultArg(rampTime, 0);\n\t\tif (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM || this.units === Tone.Type.Decibels){\n\t\t\tthis.exponentialRampToValue(value, rampTime, startTime);\n\t\t} else {\n\t\t\tthis.linearRampToValue(value, rampTime, startTime);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * The LFO created by the signal instance. If none\n\t * was created, this is null.\n\t * @type {Tone.LFO}\n\t * @readOnly\n\t * @memberOf Tone.Param#\n\t * @name lfo\n\t */\n\tObject.defineProperty(Tone.Param.prototype, \"lfo\", {\n\t\tget : function(){\n\t\t\treturn this._lfo;\n\t\t}\n\t});\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Param} this\n\t */\n\tTone.Param.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param = null;\n\t\tif (this._lfo){\n\t\t\tthis._lfo.dispose();\n\t\t\tthis._lfo = null;\n\t\t}\n\t\treturn this;\n\t};\n\n\treturn Tone.Param;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

Creates a signal that oscillates between -1.0 and 1.0.\n * By default, the oscillation takes the form of a sinusoidal\n * shape ('sine'). Additional types include 'triangle',\n * 'sawtooth' and 'square'. The frequency defaults to\n * 440 oscillations per second (440Hz, equal to the pitch of an\n * 'A' note).

\n *\n *

Set the type of oscillation with setType(), or by instantiating a\n * specific oscillator: p5.SinOsc, p5.TriOsc, p5.SqrOsc, or p5.SawOsc.\n *

\n *\n * @class p5.Oscillator\n * @constructor\n * @param {Number} [freq] frequency defaults to 440Hz\n * @param {String} [type] type of oscillator. Options:\n * 'sine' (default), 'triangle',\n * 'sawtooth', 'square'\n * @example\n *
\n * let osc, playing, freq, amp;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator('sine');\n * }\n *\n * function draw() {\n * background(220)\n * freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n * amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n *\n * text('tap to play', 20, 20);\n * text('freq: ' + freq, 20, 40);\n * text('amp: ' + amp, 20, 60);\n *\n * if (playing) {\n * // smooth the transitions by 0.1 seconds\n * osc.freq(freq, 0.1);\n * osc.amp(amp, 0.1);\n * }\n * }\n *\n * function playOscillator() {\n * // starting an oscillator on a user gesture will enable audio\n * // in browsers that have a strict autoplay policy.\n * // See also: userStartAudio();\n * osc.start();\n * playing = true;\n * }\n *\n * function mouseReleased() {\n * // ramp amplitude to 0 over 0.5 seconds\n * osc.amp(0, 0.5);\n * playing = false;\n * }\n *
\n */\n p5.Oscillator = function (freq, type) {\n if (typeof freq === 'string') {\n let f = type;\n type = freq;\n freq = f;\n }\n if (typeof type === 'number') {\n let f = type;\n type = freq;\n freq = f;\n }\n this.started = false;\n\n // components\n this.phaseAmount = undefined;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.f = freq || 440.0; // frequency\n this.oscillator.type = type || 'sine';\n this.oscillator.frequency.setValueAtTime(\n this.f,\n p5sound.audiocontext.currentTime\n );\n\n // connections\n this.output = p5sound.audiocontext.createGain();\n\n this._freqMods = []; // modulators connected to this oscillator's frequency\n\n // set default output gain to 0.5\n this.output.gain.value = 0.5;\n this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n\n this.oscillator.connect(this.output);\n // stereo panning\n this.panPosition = 0.0;\n this.connection = p5sound.input; // connect to p5sound by default\n this.panner = new p5.Panner(this.output, this.connection, 1);\n\n //array of math operation signal chaining\n this.mathOps = [this.output];\n\n // add to the soundArray so we can dispose of the osc later\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start an oscillator.\n *\n * Starting an oscillator on a user gesture will enable audio in browsers\n * that have a strict autoplay policy, including Chrome and most mobile\n * devices. See also: `userStartAudio()`.\n *\n * @method start\n * @for p5.Oscillator\n * @param {Number} [time] startTime in seconds from now.\n * @param {Number} [frequency] frequency in Hz.\n */\n p5.Oscillator.prototype.start = function (time, f) {\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n }\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n\n // set old osc free to be garbage collected (memory)\n if (this.oscillator) {\n this.oscillator.disconnect();\n delete this.oscillator;\n }\n\n // var detune = this.oscillator.frequency.value;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.value = Math.abs(freq);\n this.oscillator.type = type;\n // this.oscillator.detune.value = detune;\n this.oscillator.connect(this.output);\n time = time || 0;\n this.oscillator.start(time + p5sound.audiocontext.currentTime);\n this.freqNode = this.oscillator.frequency;\n\n // if other oscillators are already connected to this osc's freq\n for (var i in this._freqMods) {\n if (typeof this._freqMods[i].connect !== 'undefined') {\n this._freqMods[i].connect(this.oscillator.frequency);\n }\n }\n\n this.started = true;\n }\n };\n\n /**\n * Stop an oscillator. Accepts an optional parameter\n * to determine how long (in seconds from now) until the\n * oscillator stops.\n *\n * @method stop\n * @for p5.Oscillator\n * @param {Number} secondsFromNow Time, in seconds from now.\n */\n p5.Oscillator.prototype.stop = function (time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n this.started = false;\n }\n };\n\n /**\n * Set the amplitude between 0 and 1.0. Or, pass in an object\n * such as an oscillator to modulate amplitude with an audio signal.\n *\n * @method amp\n * @for p5.Oscillator\n * @param {Number|Object} vol between 0 and 1.0\n * or a modulating signal/oscillator\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @return {AudioParam} gain If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's\n * gain/amplitude/volume)\n */\n p5.Oscillator.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n if (typeof vol === 'number') {\n var now = p5sound.audiocontext.currentTime;\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n } else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // these are now the same thing\n p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n\n p5.Oscillator.prototype.getAmp = function () {\n return this.output.gain.value;\n };\n\n /**\n * Set frequency of an oscillator to a value. Or, pass in an object\n * such as an oscillator to modulate the frequency with an audio signal.\n *\n * @method freq\n * @for p5.Oscillator\n * @param {Number|Object} Frequency Frequency in Hz\n * or modulating signal/oscillator\n * @param {Number} [rampTime] Ramp time (in seconds)\n * @param {Number} [timeFromNow] Schedule this event to happen\n * at x seconds from now\n * @return {AudioParam} Frequency If no value is provided,\n * returns the Web Audio API\n * AudioParam that controls\n * this oscillator's frequency\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playOscillator);\n * osc = new p5.Oscillator(300);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playOscillator() {\n * osc.start();\n * osc.amp(0.5);\n * // start at 700Hz\n * osc.freq(700);\n * // ramp to 60Hz over 0.7 seconds\n * osc.freq(60, 0.7);\n * osc.amp(0, 0.1, 0.7);\n * }\n *
\n */\n p5.Oscillator.prototype.freq = function (val, rampTime = 0, tFromNow = 0) {\n if (typeof val === 'number' && !isNaN(val)) {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n\n if (rampTime === 0) {\n this.oscillator.frequency.setValueAtTime(val, tFromNow + now);\n } else {\n if (val > 0) {\n this.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n } else {\n this.oscillator.frequency.linearRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n }\n }\n\n // reset phase if oscillator has a phase\n if (this.phaseAmount) {\n this.phase(this.phaseAmount);\n }\n } else if (val) {\n if (val.output) {\n val = val.output;\n }\n val.connect(this.oscillator.frequency);\n\n // keep track of what is modulating this param\n // so it can be re-connected if\n this._freqMods.push(val);\n } else {\n // return the Frequency Node\n return this.oscillator.frequency;\n }\n };\n\n p5.Oscillator.prototype.getFreq = function () {\n return this.oscillator.frequency.value;\n };\n\n /**\n * Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n *\n * @method setType\n * @for p5.Oscillator\n * @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n */\n p5.Oscillator.prototype.setType = function (type) {\n this.oscillator.type = type;\n };\n\n p5.Oscillator.prototype.getType = function () {\n return this.oscillator.type;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.Oscillator\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.Oscillator.prototype.connect = function (unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n } else if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n this.connection = unit.input;\n } else {\n this.panner.connect(unit);\n this.connection = unit;\n }\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.Oscillator\n */\n p5.Oscillator.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n if (this.output) {\n this.output.connect(this.panner);\n }\n }\n this.oscMods = [];\n };\n\n /**\n * Pan between Left (-1) and Right (1)\n *\n * @method pan\n * @for p5.Oscillator\n * @param {Number} panning Number between -1 and 1\n * @param {Number} timeFromNow schedule this event to happen\n * seconds from now\n */\n p5.Oscillator.prototype.pan = function (pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n p5.Oscillator.prototype.getPan = function () {\n return this.panPosition;\n };\n\n // get rid of the oscillator\n p5.Oscillator.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.oscillator) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.disconnect();\n this.panner = null;\n this.oscillator = null;\n }\n // if it is a Pulse\n if (this.osc2) {\n this.osc2.dispose();\n }\n };\n\n /**\n * Set the phase of an oscillator between 0.0 and 1.0.\n * In this implementation, phase is a delay time\n * based on the oscillator's current frequency.\n *\n * @method phase\n * @for p5.Oscillator\n * @param {Number} phase float between 0.0 and 1.0\n */\n p5.Oscillator.prototype.phase = function (p) {\n var delayAmt = p5.prototype.map(p, 0, 1.0, 0, 1 / this.f);\n var now = p5sound.audiocontext.currentTime;\n\n this.phaseAmount = p;\n\n if (!this.dNode) {\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n // put the delay node in between output and panner\n this.oscillator.disconnect();\n this.oscillator.connect(this.dNode);\n this.dNode.connect(this.output);\n }\n\n // set delay time to match phase:\n this.dNode.delayTime.setValueAtTime(delayAmt, now);\n };\n\n // ========================== //\n // SIGNAL MATH FOR MODULATION //\n // ========================== //\n\n // return sigChain(this, scale, thisChain, nextChain, Scale);\n var sigChain = function (o, mathObj, thisChain, nextChain, type) {\n var chainSource = o.oscillator;\n // if this type of math already exists in the chain, replace it\n for (var i in o.mathOps) {\n if (o.mathOps[i] instanceof type) {\n chainSource.disconnect();\n o.mathOps[i].dispose();\n thisChain = i;\n // assume nextChain is output gain node unless...\n if (thisChain < o.mathOps.length - 2) {\n nextChain = o.mathOps[i + 1];\n }\n }\n }\n if (thisChain === o.mathOps.length - 1) {\n o.mathOps.push(nextChain);\n }\n // assume source is the oscillator unless i > 0\n if (i > 0) {\n chainSource = o.mathOps[i - 1];\n }\n chainSource.disconnect();\n chainSource.connect(mathObj);\n mathObj.connect(nextChain);\n o.mathOps[thisChain] = mathObj;\n return o;\n };\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method again\n * will override the initial add() with a new value.\n *\n * @method add\n * @for p5.Oscillator\n * @param {Number} number Constant number to add\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n *\n */\n p5.Oscillator.prototype.add = function (num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Oscillator's output amplitude\n * by a fixed value (i.e. turn it up!). Calling this method\n * again will override the initial mult() with a new value.\n *\n * @method mult\n * @for p5.Oscillator\n * @param {Number} number Constant number to multiply\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with multiplied output\n */\n p5.Oscillator.prototype.mult = function (num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this oscillator's amplitude values to a given\n * range, and return the oscillator. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Oscillator\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Oscillator} Oscillator Returns this oscillator\n * with scaled output\n */\n p5.Oscillator.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n } else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n var thisChain = this.mathOps.length - 1;\n var nextChain = this.output;\n return sigChain(this, scale, thisChain, nextChain, Scale);\n\n // this.output.disconnect();\n // this.output.connect(scale)\n };\n\n // ============================== //\n // SinOsc, TriOsc, SqrOsc, SawOsc //\n // ============================== //\n\n /**\n * Constructor: new p5.SinOsc().\n * This creates a Sine Wave Oscillator and is\n * equivalent to new p5.Oscillator('sine')\n * or creating a p5.Oscillator and then calling\n * its method setType('sine').\n * See p5.Oscillator for methods.\n *\n * @class p5.SinOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SinOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'sine');\n };\n\n p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.TriOsc().\n * This creates a Triangle Wave Oscillator and is\n * equivalent to new p5.Oscillator('triangle')\n * or creating a p5.Oscillator and then calling\n * its method setType('triangle').\n * See p5.Oscillator for methods.\n *\n * @class p5.TriOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.TriOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'triangle');\n };\n\n p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SawOsc().\n * This creates a SawTooth Wave Oscillator and is\n * equivalent to new p5.Oscillator('sawtooth')\n * or creating a p5.Oscillator and then calling\n * its method setType('sawtooth').\n * See p5.Oscillator for methods.\n *\n * @class p5.SawOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SawOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n };\n\n p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Constructor: new p5.SqrOsc().\n * This creates a Square Wave Oscillator and is\n * equivalent to new p5.Oscillator('square')\n * or creating a p5.Oscillator and then calling\n * its method setType('square').\n * See p5.Oscillator for methods.\n *\n * @class p5.SqrOsc\n * @constructor\n * @extends p5.Oscillator\n * @param {Number} [freq] Set the frequency\n */\n p5.SqrOsc = function (freq) {\n p5.Oscillator.call(this, freq, 'square');\n };\n\n p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n});\n","define([\"Tone/core/Tone\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline class for scheduling and maintaining state\n\t * along a timeline. All events must have a \"time\" property. \n\t * Internally, events are stored in time order for fast \n\t * retrieval.\n\t * @extends {Tone}\n\t * @param {Positive} [memory=Infinity] The number of previous events that are retained.\n\t */\n\tTone.Timeline = function(){\n\n\t\tvar options = this.optionsObject(arguments, [\"memory\"], Tone.Timeline.defaults);\n\n\t\t/**\n\t\t * The array of scheduled timeline events\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._timeline = [];\n\n\t\t/**\n\t\t * An array of items to remove from the list. \n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._toRemove = [];\n\n\t\t/**\n\t\t * Flag if the tieline is mid iteration\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._iterating = false;\n\n\t\t/**\n\t\t * The memory of the timeline, i.e.\n\t\t * how many events in the past it will retain\n\t\t * @type {Positive}\n\t\t */\n\t\tthis.memory = options.memory;\n\t};\n\n\tTone.extend(Tone.Timeline);\n\n\t/**\n\t * the default parameters\n\t * @static\n\t * @const\n\t */\n\tTone.Timeline.defaults = {\n\t\t\"memory\" : Infinity\n\t};\n\n\t/**\n\t * The number of items in the timeline.\n\t * @type {Number}\n\t * @memberOf Tone.Timeline#\n\t * @name length\n\t * @readOnly\n\t */\n\tObject.defineProperty(Tone.Timeline.prototype, \"length\", {\n\t\tget : function(){\n\t\t\treturn this._timeline.length;\n\t\t}\n\t});\n\n\t/**\n\t * Insert an event object onto the timeline. Events must have a \"time\" attribute.\n\t * @param {Object} event The event object to insert into the \n\t * timeline. \n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.add = function(event){\n\t\t//the event needs to have a time attribute\n\t\tif (this.isUndef(event.time)){\n\t\t\tthrow new Error(\"Tone.Timeline: events must have a time attribute\");\n\t\t}\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(event.time);\n\t\t\tthis._timeline.splice(index + 1, 0, event);\n\t\t} else {\n\t\t\tthis._timeline.push(event);\t\t\t\n\t\t}\n\t\t//if the length is more than the memory, remove the previous ones\n\t\tif (this.length > this.memory){\n\t\t\tvar diff = this.length - this.memory;\n\t\t\tthis._timeline.splice(0, diff);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event from the timeline.\n\t * @param {Object} event The event object to remove from the list.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.remove = function(event){\n\t\tif (this._iterating){\n\t\t\tthis._toRemove.push(event);\n\t\t} else {\n\t\t\tvar index = this._timeline.indexOf(event);\n\t\t\tif (index !== -1){\n\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Get the nearest event whose time is less than or equal to the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object set after that time.\n\t */\n\tTone.Timeline.prototype.get = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index !== -1){\n\t\t\treturn this._timeline[index];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Return the first event in the timeline without removing it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.peek = function(){\n\t\treturn this._timeline[0];\n\t};\n\n\t/**\n\t * Return the first event in the timeline and remove it\n\t * @returns {Object} The first event object\n\t */\n\tTone.Timeline.prototype.shift = function(){\n\t\treturn this._timeline.shift();\n\t};\n\n\t/**\n\t * Get the event which is scheduled after the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object after the given time\n\t */\n\tTone.Timeline.prototype.getAfter = function(time){\n\t\tvar index = this._search(time);\n\t\tif (index + 1 < this._timeline.length){\n\t\t\treturn this._timeline[index + 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Get the event before the event at the given time.\n\t * @param {Number} time The time to query.\n\t * @returns {Object} The event object before the given time\n\t */\n\tTone.Timeline.prototype.getBefore = function(time){\n\t\tvar len = this._timeline.length;\n\t\t//if it's after the last item, return the last item\n\t\tif (len > 0 && this._timeline[len - 1].time < time){\n\t\t\treturn this._timeline[len - 1];\n\t\t}\n\t\tvar index = this._search(time);\n\t\tif (index - 1 >= 0){\n\t\t\treturn this._timeline[index - 1];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t};\n\n\t/**\n\t * Cancel events after the given time\n\t * @param {Number} time The time to query.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancel = function(after){\n\t\tif (this._timeline.length > 1){\n\t\t\tvar index = this._search(after);\n\t\t\tif (index >= 0){\n\t\t\t\tif (this._timeline[index].time === after){\n\t\t\t\t\t//get the first item with that time\n\t\t\t\t\tfor (var i = index; i >= 0; i--){\n\t\t\t\t\t\tif (this._timeline[i].time === after){\n\t\t\t\t\t\t\tindex = i;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index);\n\t\t\t\t} else {\n\t\t\t\t\tthis._timeline = this._timeline.slice(0, index + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t} else if (this._timeline.length === 1){\n\t\t\t//the first item's time\n\t\t\tif (this._timeline[0].time >= after){\n\t\t\t\tthis._timeline = [];\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Cancel events before or equal to the given time.\n\t * @param {Number} time The time to cancel before.\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.cancelBefore = function(time){\n\t\tif (this._timeline.length){\n\t\t\tvar index = this._search(time);\n\t\t\tif (index >= 0){\n\t\t\t\tthis._timeline = this._timeline.slice(index + 1);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Does a binary serach on the timeline array and returns the \n\t * nearest event index whose time is after or equal to the given time.\n\t * If a time is searched before the first index in the timeline, -1 is returned.\n\t * If the time is after the end, the index of the last item is returned.\n\t * @param {Number} time \n\t * @return {Number} the index in the timeline array \n\t * @private\n\t */\n\tTone.Timeline.prototype._search = function(time){\n\t\tvar beginning = 0;\n\t\tvar len = this._timeline.length;\n\t\tvar end = len;\n\t\tif (len > 0 && this._timeline[len - 1].time <= time){\n\t\t\treturn len - 1;\n\t\t}\n\t\twhile (beginning < end){\n\t\t\t// calculate the midpoint for roughly equal partition\n\t\t\tvar midPoint = Math.floor(beginning + (end - beginning) / 2);\n\t\t\tvar event = this._timeline[midPoint];\n\t\t\tvar nextEvent = this._timeline[midPoint + 1];\n\t\t\tif (event.time === time){\n\t\t\t\t//choose the last one that has the same time\n\t\t\t\tfor (var i = midPoint; i < this._timeline.length; i++){\n\t\t\t\t\tvar testEvent = this._timeline[i];\n\t\t\t\t\tif (testEvent.time === time){\n\t\t\t\t\t\tmidPoint = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time < time && nextEvent.time > time){\n\t\t\t\treturn midPoint;\n\t\t\t} else if (event.time > time){\n\t\t\t\t//search lower\n\t\t\t\tend = midPoint;\n\t\t\t} else if (event.time < time){\n\t\t\t\t//search upper\n\t\t\t\tbeginning = midPoint + 1;\n\t\t\t} \n\t\t}\n\t\treturn -1;\n\t};\n\n\t/**\n\t * Internal iterator. Applies extra safety checks for \n\t * removing items from the array. \n\t * @param {Function} callback \n\t * @param {Number=} lowerBound \n\t * @param {Number=} upperBound \n\t * @private\n\t */\n\tTone.Timeline.prototype._iterate = function(callback, lowerBound, upperBound){\n\t\tthis._iterating = true;\n\t\tlowerBound = this.defaultArg(lowerBound, 0);\n\t\tupperBound = this.defaultArg(upperBound, this._timeline.length - 1);\n\t\tfor (var i = lowerBound; i <= upperBound; i++){\n\t\t\tcallback(this._timeline[i]);\n\t\t}\n\t\tthis._iterating = false;\n\t\tif (this._toRemove.length > 0){\n\t\t\tfor (var j = 0; j < this._toRemove.length; j++){\n\t\t\t\tvar index = this._timeline.indexOf(this._toRemove[j]);\n\t\t\t\tif (index !== -1){\n\t\t\t\t\tthis._timeline.splice(index, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._toRemove = [];\n\t\t}\n\t};\n\n\t/**\n\t * Iterate over everything in the array\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEach = function(callback){\n\t\tthis._iterate(callback);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or before the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachBefore = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(callback, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array after the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAfter = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at or after the given time. Similar to \n\t * forEachAfter, but includes the item(s) at the given time.\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachFrom = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar lowerBound = this._search(time);\n\t\t//work backwards until the event time is less than time\n\t\twhile (lowerBound >= 0 && this._timeline[lowerBound].time >= time){\n\t\t\tlowerBound--;\n\t\t}\n\t\tthis._iterate(callback, lowerBound + 1);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Iterate over everything in the array at the given time\n\t * @param {Number} time The time to check if items are before\n\t * @param {Function} callback The callback to invoke with every item\n\t * @returns {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.forEachAtTime = function(time, callback){\n\t\t//iterate over the items in reverse so that removing an item doesn't break things\n\t\tvar upperBound = this._search(time);\n\t\tif (upperBound !== -1){\n\t\t\tthis._iterate(function(event){\n\t\t\t\tif (event.time === time){\n\t\t\t\t\tcallback(event);\n\t\t\t\t} \n\t\t\t}, 0, upperBound);\n\t\t}\n\t\treturn this;\n\t};\n\n\t/**\n\t * Clean up.\n\t * @return {Tone.Timeline} this\n\t */\n\tTone.Timeline.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._timeline = null;\n\t\tthis._toRemove = null;\n\t};\n\n\treturn Tone.Timeline;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Multiply\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Negate the incoming signal. i.e. an input signal of 10 will output -10\n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var neg = new Tone.Negate();\n\t * var sig = new Tone.Signal(-2).connect(neg);\n\t * //output of neg is positive 2. \n\t */\n\tTone.Negate = function(){\n\t\t/**\n\t\t * negation is done by multiplying by -1\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = this.input = this.output = new Tone.Multiply(-1);\n\t};\n\n\tTone.extend(Tone.Negate, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Negate} this\n\t */\n\tTone.Negate.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Negate;\n});","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Multiply\", \"Tone/signal/WaveShaper\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class GreaterThanZero outputs 1 when the input is strictly greater than zero\n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var gt0 = new Tone.GreaterThanZero();\n\t * var sig = new Tone.Signal(0.01).connect(gt0);\n\t * //the output of gt0 is 1. \n\t * sig.value = 0;\n\t * //the output of gt0 is 0. \n\t */\n\tTone.GreaterThanZero = function(){\n\t\t\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._thresh = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val <= 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}, 127);\n\n\t\t/**\n\t\t * scale the first thresholded signal by a large value.\n\t\t * this will help with values which are very close to 0\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._scale = this.input = new Tone.Multiply(10000);\n\n\t\t//connections\n\t\tthis._scale.connect(this._thresh);\n\t};\n\n\tTone.extend(Tone.GreaterThanZero, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThanZero} this\n\t */\n\tTone.GreaterThanZero.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._scale.dispose();\n\t\tthis._scale = null;\n\t\tthis._thresh.dispose();\n\t\tthis._thresh = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThanZero;\n});","define([\"Tone/core/Tone\", \"Tone/signal/TimelineSignal\", \"Tone/core/TimelineState\", \n\t\"Tone/core/Emitter\", \"Tone/core/Context\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A sample accurate clock which provides a callback at the given rate. \n\t * While the callback is not sample-accurate (it is still susceptible to\n\t * loose JS timing), the time passed in as the argument to the callback\n\t * is precise. For most applications, it is better to use Tone.Transport\n\t * instead of the Clock by itself since you can synchronize multiple callbacks.\n\t *\n\t * \t@constructor\n\t * @extends {Tone.Emitter}\n\t * \t@param {function} callback The callback to be invoked with the time of the audio event\n\t * \t@param {Frequency} frequency The rate of the callback\n\t * \t@example\n\t * //the callback will be invoked approximately once a second\n\t * //and will print the time exactly once a second apart.\n\t * var clock = new Tone.Clock(function(time){\n\t * \tconsole.log(time);\n\t * }, 1);\n\t */\n\tTone.Clock = function(){\n\n\t\tTone.Emitter.call(this);\n\n\t\tvar options = this.optionsObject(arguments, [\"callback\", \"frequency\"], Tone.Clock.defaults);\n\n\t\t/**\n\t\t * The callback function to invoke at the scheduled tick.\n\t\t * @type {Function}\n\t\t */\n\t\tthis.callback = options.callback;\n\n\t\t/**\n\t\t * The next time the callback is scheduled.\n\t\t * @type {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextTick = 0;\n\n\t\t/**\n\t\t * The last state of the clock.\n\t\t * @type {State}\n\t\t * @private\n\t\t */\n\t\tthis._lastState = Tone.State.Stopped;\n\n\t\t/**\n\t\t * The rate the callback function should be invoked. \n\t\t * @type {BPM}\n\t\t * @signal\n\t\t */\n\t\tthis.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency);\n\t\tthis._readOnly(\"frequency\");\n\n\t\t/**\n\t\t * The number of times the callback was invoked. Starts counting at 0\n\t\t * and increments after the callback was invoked. \n\t\t * @type {Ticks}\n\t\t * @readOnly\n\t\t */\n\t\tthis.ticks = 0;\n\n\t\t/**\n\t\t * The state timeline\n\t\t * @type {Tone.TimelineState}\n\t\t * @private\n\t\t */\n\t\tthis._state = new Tone.TimelineState(Tone.State.Stopped);\n\n\t\t/**\n\t\t * The loop function bound to its context. \n\t\t * This is necessary to remove the event in the end.\n\t\t * @type {Function}\n\t\t * @private\n\t\t */\n\t\tthis._boundLoop = this._loop.bind(this);\n\n\t\t//bind a callback to the worker thread\n \tthis.context.on(\"tick\", this._boundLoop);\n\t};\n\n\tTone.extend(Tone.Clock, Tone.Emitter);\n\n\t/**\n\t * The defaults\n\t * @const\n\t * @type {Object}\n\t */\n\tTone.Clock.defaults = {\n\t\t\"callback\" : Tone.noOp,\n\t\t\"frequency\" : 1,\n\t\t\"lookAhead\" : \"auto\",\n\t};\n\n\t/**\n\t * Returns the playback state of the source, either \"started\", \"stopped\" or \"paused\".\n\t * @type {Tone.State}\n\t * @readOnly\n\t * @memberOf Tone.Clock#\n\t * @name state\n\t */\n\tObject.defineProperty(Tone.Clock.prototype, \"state\", {\n\t\tget : function(){\n\t\t\treturn this._state.getValueAtTime(this.now());\n\t\t}\n\t});\n\n\t/**\n\t * Start the clock at the given time. Optionally pass in an offset\n\t * of where to start the tick counter from.\n\t * @param {Time} time The time the clock should start\n\t * @param {Ticks=} offset Where the tick counter starts counting from.\n\t * @return {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.start = function(time, offset){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) !== Tone.State.Started){\n\t\t\tthis._state.add({\n\t\t\t\t\"state\" : Tone.State.Started, \n\t\t\t\t\"time\" : time,\n\t\t\t\t\"offset\" : offset\n\t\t\t});\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * Stop the clock. Stopping the clock resets the tick counter to 0.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t * @example\n\t * clock.stop();\n\t */\n\tTone.Clock.prototype.stop = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tthis._state.cancel(time);\n\t\tthis._state.setStateAtTime(Tone.State.Stopped, time);\n\t\treturn this;\t\n\t};\n\n\n\t/**\n\t * Pause the clock. Pausing does not reset the tick counter.\n\t * @param {Time} [time=now] The time when the clock should stop.\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.pause = function(time){\n\t\ttime = this.toSeconds(time);\n\t\tif (this._state.getValueAtTime(time) === Tone.State.Started){\n\t\t\tthis._state.setStateAtTime(Tone.State.Paused, time);\n\t\t}\n\t\treturn this;\t\n\t};\n\n\t/**\n\t * The scheduling loop.\n\t * @param {Number} time The current page time starting from 0\n\t * when the page was loaded.\n\t * @private\n\t */\n\tTone.Clock.prototype._loop = function(){\n\t\t//get the frequency value to compute the value of the next loop\n\t\tvar now = this.now();\n\t\t//if it's started\n\t\tvar lookAhead = this.context.lookAhead;\n\t\tvar updateInterval = this.context.updateInterval;\n\t\tvar lagCompensation = this.context.lag * 2;\n\t\tvar loopInterval = now + lookAhead + updateInterval + lagCompensation;\n\t\twhile (loopInterval > this._nextTick && this._state){\n\t\t\tvar currentState = this._state.getValueAtTime(this._nextTick);\n\t\t\tif (currentState !== this._lastState){\n\t\t\t\tthis._lastState = currentState;\n\t\t\t\tvar event = this._state.get(this._nextTick);\n\t\t\t\t// emit an event\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\t//correct the time\n\t\t\t\t\tthis._nextTick = event.time;\n\t\t\t\t\tif (!this.isUndef(event.offset)){\n\t\t\t\t\t\tthis.ticks = event.offset;\n\t\t\t\t\t}\n\t\t\t\t\tthis.emit(\"start\", event.time, this.ticks);\n\t\t\t\t} else if (currentState === Tone.State.Stopped){\n\t\t\t\t\tthis.ticks = 0;\n\n\t\t\t\t\tthis.emit(\"stop\", event.time);\n\t\t\t\t} else if (currentState === Tone.State.Paused){\n\t\t\t\t\tthis.emit(\"pause\", event.time);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar tickTime = this._nextTick;\n\t\t\tif (this.frequency){\n\t\t\t\tthis._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick);\n\t\t\t\tif (currentState === Tone.State.Started){\n\t\t\t\t\tthis.callback(tickTime);\n\t\t\t\t\tthis.ticks++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state at the given time.\n\t * @param {Time} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t * @example\n\t * clock.start(\"+0.1\");\n\t * clock.getStateAtTime(\"+0.1\"); //returns \"started\"\n\t */\n\tTone.Clock.prototype.getStateAtTime = function(time){\n\t\ttime = this.toSeconds(time);\n\t\treturn this._state.getValueAtTime(time);\n\t};\n\n\t/**\n\t * Clean up\n\t * @returns {Tone.Clock} this\n\t */\n\tTone.Clock.prototype.dispose = function(){\n\t\tTone.Emitter.prototype.dispose.call(this);\n\t\tthis.context.off(\"tick\", this._boundLoop);\n\t\tthis._writable(\"frequency\");\n\t\tthis.frequency.dispose();\n\t\tthis.frequency = null;\n\t\tthis._boundLoop = null;\n\t\tthis._nextTick = Infinity;\n\t\tthis.callback = null;\n\t\tthis._state.dispose();\n\t\tthis._state = null;\n\t};\n\n\treturn Tone.Clock;\n});","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var AudioVoice = require('audioVoice');\n var noteToFreq = require('helpers').noteToFreq;\n\n var DEFAULT_SUSTAIN = 0.15;\n\n /**\n * A MonoSynth is used as a single voice for sound synthesis.\n * This is a class to be used in conjunction with the PolySynth\n * class. Custom synthetisers should be built inheriting from\n * this class.\n *\n * @class p5.MonoSynth\n * @constructor\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n **/\n\n p5.MonoSynth = function () {\n AudioVoice.call(this);\n\n this.oscillator = new p5.Oscillator();\n\n this.env = new p5.Envelope();\n this.env.setRange(1, 0);\n this.env.setExp(true);\n\n //set params\n this.setADSR(0.02, 0.25, 0.05, 0.35);\n\n // oscillator --> env --> this.output (gain) --> p5.soundOut\n this.oscillator.disconnect();\n this.oscillator.connect(this.output);\n\n this.env.disconnect();\n this.env.setInput(this.output.gain);\n\n // reset oscillator gain to 1.0\n this.oscillator.output.gain.value = 1.0;\n\n this.oscillator.start();\n this.connect();\n\n p5sound.soundArray.push(this);\n };\n\n p5.MonoSynth.prototype = Object.create(p5.AudioVoice.prototype);\n\n /**\n * Play tells the MonoSynth to start playing a note. This method schedules\n * the calling of .triggerAttack and .triggerRelease.\n *\n * @method play\n * @for p5.MonoSynth\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope. Defaults to 0.15 seconds.\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * let note = random(['Fb4', 'G4']);\n * // note velocity (volume, from 0 to 1)\n * let velocity = random();\n * // time from now (in seconds)\n * let time = 0;\n * // note duration (in seconds)\n * let dur = 1/6;\n *\n * monoSynth.play(note, velocity, time, dur);\n * }\n *
\n *\n */\n p5.MonoSynth.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n susTime\n ) {\n this.triggerAttack(note, velocity, ~~secondsFromNow);\n this.triggerRelease(~~secondsFromNow + (susTime || DEFAULT_SUSTAIN));\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @param {String | Number} note the note you want to play, specified as a\n * frequency in Hertz (Number) or as a midi\n * value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n * See \n * Tone. Defaults to 440 hz\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @method triggerAttack\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerAttack = function (\n note,\n velocity,\n secondsFromNow = 0\n ) {\n var freq = noteToFreq(note);\n var vel = velocity || 0.1;\n this.oscillator.freq(freq, 0, secondsFromNow);\n this.env.ramp(this.output.gain, secondsFromNow, vel);\n };\n\n /**\n * Trigger the release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @param {Number} secondsFromNow time to trigger the release\n * @method triggerRelease\n * @for p5.MonoSynth\n * @example\n *
\n * let monoSynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(triggerAttack);\n * background(220);\n * text('tap here for attack, let go to release', 5, 20, width - 20);\n * monoSynth = new p5.MonoSynth();\n * }\n *\n * function triggerAttack() {\n * userStartAudio();\n *\n * monoSynth.triggerAttack(\"E3\");\n * }\n *\n * function mouseReleased() {\n * monoSynth.triggerRelease();\n * }\n *
\n */\n p5.MonoSynth.prototype.triggerRelease = function (secondsFromNow = 0) {\n this.env.ramp(this.output.gain, secondsFromNow, 0);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.MonoSynth\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n */\n p5.MonoSynth.prototype.setADSR = function (attack, decay, sustain, release) {\n this.env.setADSR(attack, decay, sustain, release);\n };\n\n /**\n * Getters and Setters\n * @property {Number} attack\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} decay\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} sustain\n * @for p5.MonoSynth\n */\n /**\n * @property {Number} release\n * @for p5.MonoSynth\n */\n Object.defineProperties(p5.MonoSynth.prototype, {\n attack: {\n get: function () {\n return this.env.aTime;\n },\n set: function (attack) {\n this.env.setADSR(\n attack,\n this.env.dTime,\n this.env.sPercent,\n this.env.rTime\n );\n },\n },\n decay: {\n get: function () {\n return this.env.dTime;\n },\n set: function (decay) {\n this.env.setADSR(\n this.env.aTime,\n decay,\n this.env.sPercent,\n this.env.rTime\n );\n },\n },\n sustain: {\n get: function () {\n return this.env.sPercent;\n },\n set: function (sustain) {\n this.env.setADSR(\n this.env.aTime,\n this.env.dTime,\n sustain,\n this.env.rTime\n );\n },\n },\n release: {\n get: function () {\n return this.env.rTime;\n },\n set: function (release) {\n this.env.setADSR(\n this.env.aTime,\n this.env.dTime,\n this.env.sPercent,\n release\n );\n },\n },\n });\n\n /**\n * MonoSynth amp\n * @method amp\n * @for p5.MonoSynth\n * @param {Number} vol desired volume\n * @param {Number} [rampTime] Time to reach new volume\n * @return {Number} new volume value\n */\n p5.MonoSynth.prototype.amp = function (vol, rampTime) {\n var t = rampTime || 0;\n if (typeof vol !== 'undefined') {\n this.oscillator.amp(vol, t);\n }\n return this.oscillator.amp().value;\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.MonoSynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n\n p5.MonoSynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.MonoSynth\n */\n p5.MonoSynth.prototype.dispose = function () {\n AudioVoice.prototype.dispose.apply(this);\n\n if (this.env) {\n this.env.dispose();\n }\n if (this.oscillator) {\n this.oscillator.dispose();\n }\n };\n});\n","'use strict';\ndefine(function () {\n var p5sound = require('master');\n\n /**\n * Base class for monophonic synthesizers. Any extensions of this class\n * should follow the API and implement the methods below in order to\n * remain compatible with p5.PolySynth();\n *\n * @class p5.AudioVoice\n * @constructor\n */\n p5.AudioVoice = function () {\n this.ac = p5sound.audiocontext;\n this.output = this.ac.createGain();\n this.connect();\n p5sound.soundArray.push(this);\n };\n\n p5.AudioVoice.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n sustime\n ) {};\n\n p5.AudioVoice.prototype.triggerAttack = function (\n note,\n velocity,\n secondsFromNow\n ) {};\n\n p5.AudioVoice.prototype.triggerRelease = function (secondsFromNow) {};\n\n p5.AudioVoice.prototype.amp = function (vol, rampTime) {};\n\n /**\n * Connect to p5 objects or Web Audio Nodes\n * @method connect\n * @for p5.AudioVoice\n * @param {Object} unit\n */\n p5.AudioVoice.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect from soundOut\n * @method disconnect\n * @for p5.AudioVoice\n */\n p5.AudioVoice.prototype.disconnect = function () {\n this.output.disconnect();\n };\n\n p5.AudioVoice.prototype.dispose = function () {\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n\n return p5.AudioVoice;\n});\n","'use strict';\ndefine(function (require) {\n var p5sound = require('master');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n var noteToFreq = require('helpers').noteToFreq;\n\n /**\n * An AudioVoice is used as a single voice for sound synthesis.\n * The PolySynth class holds an array of AudioVoice, and deals\n * with voices allocations, with setting notes to be played, and\n * parameters to be set.\n *\n * @class p5.PolySynth\n * @constructor\n *\n * @param {Number} [synthVoice] A monophonic synth voice inheriting\n * the AudioVoice class. Defaults to p5.MonoSynth\n * @param {Number} [maxVoices] Number of voices, defaults to 8;\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n **/\n p5.PolySynth = function (audioVoice, maxVoices) {\n //audiovoices will contain maxVoices many monophonic synths\n this.audiovoices = [];\n\n /**\n * An object that holds information about which notes have been played and\n * which notes are currently being played. New notes are added as keys\n * on the fly. While a note has been attacked, but not released, the value of the\n * key is the audiovoice which is generating that note. When notes are released,\n * the value of the key becomes undefined.\n * @property notes\n */\n this.notes = {};\n\n //indices of the most recently used, and least recently used audiovoice\n this._newest = 0;\n this._oldest = 0;\n\n /**\n * A PolySynth must have at least 1 voice, defaults to 8\n * @property polyvalue\n */\n this.maxVoices = maxVoices || 8;\n\n /**\n * Monosynth that generates the sound for each note that is triggered. The\n * p5.PolySynth defaults to using the p5.MonoSynth as its voice.\n * @property AudioVoice\n */\n this.AudioVoice = audioVoice === undefined ? p5.MonoSynth : audioVoice;\n\n /**\n * This value must only change as a note is attacked or released. Due to delay\n * and sustain times, Tone.TimelineSignal is required to schedule the change in value.\n * @private\n * @property {Tone.TimelineSignal} _voicesInUse\n */\n this._voicesInUse = new TimelineSignal(0);\n\n this.output = p5sound.audiocontext.createGain();\n this.connect();\n\n //Construct the appropriate number of audiovoices\n this._allocateVoices();\n p5sound.soundArray.push(this);\n };\n\n /**\n * Construct the appropriate number of audiovoices\n * @private\n * @for p5.PolySynth\n * @method _allocateVoices\n */\n p5.PolySynth.prototype._allocateVoices = function () {\n for (var i = 0; i < this.maxVoices; i++) {\n this.audiovoices.push(new this.AudioVoice());\n this.audiovoices[i].disconnect();\n this.audiovoices[i].connect(this.output);\n }\n };\n\n /**\n * Play a note by triggering noteAttack and noteRelease with sustain time\n *\n * @method play\n * @for p5.PolySynth\n * @param {Number} [note] midi note to play (ranging from 0 to 127 - 60 being a middle C)\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)\n * @param {Number} [secondsFromNow] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let polySynth;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSynth);\n * background(220);\n * text('click to play', 20, 20);\n *\n * polySynth = new p5.PolySynth();\n * }\n *\n * function playSynth() {\n * userStartAudio();\n *\n * // note duration (in seconds)\n * let dur = 1.5;\n *\n * // time from now (in seconds)\n * let time = 0;\n *\n * // velocity (volume, from 0 to 1)\n * let vel = 0.1;\n *\n * // notes can overlap with each other\n * polySynth.play('G2', vel, 0, dur);\n * polySynth.play('C3', vel, time += 1/3, dur);\n * polySynth.play('G3', vel, time += 1/3, dur);\n * }\n *
\n */\n p5.PolySynth.prototype.play = function (\n note,\n velocity,\n secondsFromNow,\n susTime = 1\n ) {\n this.noteAttack(note, velocity, secondsFromNow);\n this.noteRelease(note, secondsFromNow + susTime);\n };\n\n /**\n * noteADSR sets the envelope for a specific note that has just been triggered.\n * Using this method modifies the envelope of whichever audiovoice is being used\n * to play the desired note. The envelope should be reset before noteRelease is called\n * in order to prevent the modified envelope from being used on other notes.\n *\n * @method noteADSR\n * @for p5.PolySynth\n * @param {Number} [note] Midi note on which ADSR should be set.\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n\n p5.PolySynth.prototype.noteADSR = function (\n note,\n a,\n d,\n s,\n r,\n timeFromNow = 0\n ) {\n var now = p5sound.audiocontext.currentTime;\n var t = now + timeFromNow;\n this.audiovoices[this.notes[note].getValueAtTime(t)].setADSR(a, d, s, r);\n };\n\n /**\n * Set the PolySynths global envelope. This method modifies the envelopes of each\n * monosynth so that all notes are played with this envelope.\n *\n * @method setADSR\n * @for p5.PolySynth\n * @param {Number} [attackTime] Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n **/\n p5.PolySynth.prototype.setADSR = function (a, d, s, r) {\n this.audiovoices.forEach(function (voice) {\n voice.setADSR(a, d, s, r);\n });\n };\n\n /**\n * Trigger the Attack, and Decay portion of a MonoSynth.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go.\n *\n * @method noteAttack\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * @param {Number} [velocity] velocity of the note to play (ranging from 0 to 1)/\n * @param {Number} [secondsFromNow] time from now (in seconds)\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n */\n p5.PolySynth.prototype.noteAttack = function (\n _note,\n _velocity,\n secondsFromNow = 0\n ) {\n //this value is used by this._voicesInUse\n var acTime = p5sound.audiocontext.currentTime + secondsFromNow;\n\n //Convert note to frequency if necessary. This is because entries into this.notes\n //should be based on frequency for the sake of consistency.\n var note = noteToFreq(_note);\n var velocity = _velocity || 0.1;\n\n var currentVoice;\n\n //Release the note if it is already playing\n if (this.notes[note] && this.notes[note].getValueAtTime(acTime) !== null) {\n this.noteRelease(note, 0);\n }\n\n //Check to see how many voices are in use at the time the note will start\n if (this._voicesInUse.getValueAtTime(acTime) < this.maxVoices) {\n currentVoice = Math.max(~~this._voicesInUse.getValueAtTime(acTime), 0);\n }\n //If we are exceeding the polyvalue, bump off the oldest notes and replace\n //with a new note\n else {\n currentVoice = this._oldest;\n\n var oldestNote = p5.prototype.freqToMidi(\n this.audiovoices[this._oldest].oscillator.freq().value\n );\n this.noteRelease(oldestNote);\n this._oldest = (this._oldest + 1) % (this.maxVoices - 1);\n }\n\n //Overrite the entry in the notes object. A note (frequency value)\n //corresponds to the index of the audiovoice that is playing it\n this.notes[note] = new TimelineSignal();\n this.notes[note].setValueAtTime(currentVoice, acTime);\n\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //Add 1 and schedule this value at time 't', when this note will start playing\n var previousVal =\n this._voicesInUse._searchBefore(acTime) === null\n ? 0\n : this._voicesInUse._searchBefore(acTime).value;\n this._voicesInUse.setValueAtTime(previousVal + 1, acTime);\n\n //Then update all scheduled values that follow to increase by 1\n this._updateAfter(acTime, 1);\n\n this._newest = currentVoice;\n //The audiovoice handles the actual scheduling of the note\n if (typeof velocity === 'number') {\n var maxRange = (1 / this._voicesInUse.getValueAtTime(acTime)) * 2;\n velocity = velocity > maxRange ? maxRange : velocity;\n }\n\n // use secondsFromNow because this method will add AudioContext currentTime\n this.audiovoices[currentVoice].triggerAttack(\n note,\n velocity,\n secondsFromNow\n );\n };\n\n /**\n * Private method to ensure accurate values of this._voicesInUse\n * Any time a new value is scheduled, it is necessary to increment all subsequent\n * scheduledValues after attack, and decrement all subsequent\n * scheduledValues after release\n *\n * @private\n * @for p5.PolySynth\n * @param {[type]} time [description]\n * @param {[type]} value [description]\n * @return {[type]} [description]\n */\n p5.PolySynth.prototype._updateAfter = function (time, value) {\n if (this._voicesInUse._searchAfter(time) === null) {\n return;\n } else {\n this._voicesInUse._searchAfter(time).value += value;\n var nextTime = this._voicesInUse._searchAfter(time).time;\n this._updateAfter(nextTime, value);\n }\n };\n\n /**\n * Trigger the Release of an AudioVoice note. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method noteRelease\n * @for p5.PolySynth\n * @param {Number} [note] midi note on which attack should be triggered.\n * If no value is provided, all notes will be released.\n * @param {Number} [secondsFromNow] time to trigger the release\n * @example\n *
\n * let polySynth = new p5.PolySynth();\n * let pitches = ['G', 'D', 'G', 'C'];\n * let octaves = [2, 3, 4];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playChord);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function playChord() {\n * userStartAudio();\n *\n * // play a chord: multiple notes at the same time\n * for (let i = 0; i < 4; i++) {\n * let note = random(pitches) + random(octaves);\n * polySynth.noteAttack(note, 0.1);\n * }\n * }\n *\n * function mouseReleased() {\n * // release all voices\n * polySynth.noteRelease();\n * }\n *
\n *\n */\n p5.PolySynth.prototype.noteRelease = function (_note, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n // if a note value is not provided, release all voices\n if (!_note) {\n this.audiovoices.forEach(function (voice) {\n voice.triggerRelease(tFromNow);\n });\n this._voicesInUse.setValueAtTime(0, t);\n for (var n in this.notes) {\n this.notes[n].dispose();\n delete this.notes[n];\n }\n return;\n }\n\n //Make sure note is in frequency inorder to query the this.notes object\n var note = noteToFreq(_note);\n\n if (!this.notes[note] || this.notes[note].getValueAtTime(t) === null) {\n console.warn('Cannot release a note that is not already playing');\n } else {\n //Find the scheduled change in this._voicesInUse that will be previous to this new note\n //subtract 1 and schedule this value at time 't', when this note will stop playing\n var previousVal = Math.max(\n ~~this._voicesInUse.getValueAtTime(t).value,\n 1\n );\n this._voicesInUse.setValueAtTime(previousVal - 1, t);\n //Then update all scheduled values that follow to decrease by 1 but never go below 0\n if (previousVal > 0) {\n this._updateAfter(t, -1);\n }\n\n this.audiovoices[this.notes[note].getValueAtTime(t)].triggerRelease(\n tFromNow\n );\n this.notes[note].dispose();\n delete this.notes[note];\n\n this._newest =\n this._newest === 0 ? 0 : (this._newest - 1) % (this.maxVoices - 1);\n }\n };\n\n /**\n * Connect to a p5.sound / Web Audio object.\n *\n * @method connect\n * @for p5.PolySynth\n * @param {Object} unit A p5.sound or Web Audio object\n */\n p5.PolySynth.prototype.connect = function (unit) {\n var u = unit || p5sound.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all outputs\n *\n * @method disconnect\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Get rid of the MonoSynth and free up its resources / memory.\n *\n * @method dispose\n * @for p5.PolySynth\n */\n p5.PolySynth.prototype.dispose = function () {\n this.audiovoices.forEach(function (voice) {\n voice.dispose();\n });\n\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n require('audioworklet-polyfill');\n require('shims');\n require('audiocontext');\n var p5SOUND = require('master');\n require('helpers');\n require('errorHandler');\n require('audioWorklet');\n require('panner');\n require('soundfile');\n require('amplitude');\n require('fft');\n require('signal');\n require('oscillator');\n require('envelope');\n require('pulse');\n require('noise');\n require('audioin');\n require('filter');\n require('eq');\n require('panner3d');\n require('listener3d');\n require('delay');\n require('reverb');\n require('metro');\n require('looper');\n require('soundLoop');\n require('compressor');\n require('soundRecorder');\n require('peakDetect');\n require('gain');\n require('monosynth');\n require('polysynth');\n require('distortion');\n require('audioVoice');\n require('monosynth');\n require('polysynth');\n\n return p5SOUND;\n});\n","!function(){var e,t=[];function r(e){var r=this,n={},i=-1;this.parameters.forEach(function(e,o){var s=t[++i]||(t[i]=new Float32Array(r.bufferSize));s.fill(e.value),n[o]=s}),this.processor.realm.exec(\"self.sampleRate=sampleRate=\"+this.context.sampleRate+\";self.currentTime=currentTime=\"+this.context.currentTime);var s=o(e.inputBuffer),a=o(e.outputBuffer);this.instance.process([s],[a],n)}function o(e){for(var t=[],r=0;r= this._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; 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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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);\"","export default \"function _typeof(obj) { if (typeof Symbol === \\\"function\\\" && typeof Symbol.iterator === \\\"symbol\\\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \\\"function\\\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \\\"symbol\\\" : typeof obj; }; } return _typeof(obj); }\\n\\nfunction _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, [{\\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; ++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; 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);\"","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var ac = p5sound.audiocontext;\n\n // Stereo panner\n // if there is a stereo panner node use it\n if (typeof ac.createStereoPanner !== 'undefined') {\n p5.Panner = function (input, output) {\n this.stereoPanner = this.input = ac.createStereoPanner();\n input.connect(this.stereoPanner);\n this.stereoPanner.connect(output);\n };\n\n p5.Panner.prototype.pan = function (val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n\n this.stereoPanner.pan.linearRampToValueAtTime(val, t);\n };\n\n //not implemented because stereopanner\n //node does not require this and will automatically\n //convert single channel or multichannel to stereo.\n //tested with single and stereo, not with (>2) multichannel\n p5.Panner.prototype.inputChannels = function () {};\n\n p5.Panner.prototype.connect = function (obj) {\n this.stereoPanner.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function () {\n if (this.stereoPanner) {\n this.stereoPanner.disconnect();\n }\n };\n } else {\n // if there is no createStereoPanner object\n // such as in safari 7.1.7 at the time of writing this\n // use this method to create the effect\n p5.Panner = function (input, output, numInputChannels) {\n this.input = ac.createGain();\n input.connect(this.input);\n\n this.left = ac.createGain();\n this.right = ac.createGain();\n this.left.channelInterpretation = 'discrete';\n this.right.channelInterpretation = 'discrete';\n\n // if input is stereo\n if (numInputChannels > 1) {\n this.splitter = ac.createChannelSplitter(2);\n this.input.connect(this.splitter);\n\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n } else {\n this.input.connect(this.left);\n this.input.connect(this.right);\n }\n\n this.output = ac.createChannelMerger(2);\n this.left.connect(this.output, 0, 1);\n this.right.connect(this.output, 0, 0);\n this.output.connect(output);\n };\n\n // -1 is left, +1 is right\n p5.Panner.prototype.pan = function (val, tFromNow) {\n var time = tFromNow || 0;\n var t = ac.currentTime + time;\n var v = (val + 1) / 2;\n var rightVal = Math.cos((v * Math.PI) / 2);\n var leftVal = Math.sin((v * Math.PI) / 2);\n this.left.gain.linearRampToValueAtTime(leftVal, t);\n this.right.gain.linearRampToValueAtTime(rightVal, t);\n };\n\n p5.Panner.prototype.inputChannels = function (numChannels) {\n if (numChannels === 1) {\n this.input.disconnect();\n this.input.connect(this.left);\n this.input.connect(this.right);\n } else if (numChannels === 2) {\n if (typeof this.splitter === 'undefined') {\n this.splitter = ac.createChannelSplitter(2);\n }\n this.input.disconnect();\n this.input.connect(this.splitter);\n this.splitter.connect(this.left, 1);\n this.splitter.connect(this.right, 0);\n }\n };\n\n p5.Panner.prototype.connect = function (obj) {\n this.output.connect(obj);\n };\n\n p5.Panner.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const CustomError = require('errorHandler');\n const p5sound = require('master');\n const ac = p5sound.audiocontext;\n const { midiToFreq, convertToWav, safeBufferSize } = require('helpers');\n var processorNames = require('./audioWorklet/processorNames');\n\n /**\n *

SoundFile object with a path to a file.

\n *\n *

The p5.SoundFile may not be available immediately because\n * it loads the file information asynchronously.

\n *\n *

To do something with the sound as soon as it loads\n * pass the name of a function as the second parameter.

\n *\n *

Only one file path is required. However, audio file formats\n * (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n * web browsers. If you want to ensure compatability, instead of a single\n * file path, you may include an Array of filepaths, and the browser will\n * choose a format that works.

\n *\n * @class p5.SoundFile\n * @constructor\n * @param {String|Array} path path to a sound file (String). Optionally,\n * you may include multiple file formats in\n * an array. Alternately, accepts an object\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if file fails to\n * load. This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @param {Function} [whileLoadingCallback] Name of a function to call while file\n * is loading. That function will\n * receive progress of the request to\n * load the sound file\n * (between 0 and 1) as its first\n * parameter. This progress\n * does not account for the additional\n * time needed to decode the audio data.\n *\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile = function (paths, onload, onerror, whileLoading) {\n if (typeof paths !== 'undefined') {\n if (typeof paths === 'string' || typeof paths[0] === 'string') {\n var path = p5.prototype._checkFileFormats(paths);\n this.url = path;\n } else if (typeof paths === 'object') {\n if (\n !(window.File && window.FileReader && window.FileList && window.Blob)\n ) {\n // The File API isn't supported in this browser\n throw 'Unable to load file because the File API is not supported';\n }\n }\n\n // if type is a p5.File...get the actual file\n if (paths.file) {\n paths = paths.file;\n }\n\n this.file = paths;\n }\n\n // private _onended callback, set by the method: onended(callback)\n this._onended = function () {};\n\n this._looping = false;\n this._playing = false;\n this._paused = false;\n this._pauseTime = 0;\n\n // cues for scheduling events with addCue() removeCue()\n this._cues = [];\n this._cueIDCounter = 0;\n\n // position of the most recently played sample\n this._lastPos = 0;\n this._counterNode = null;\n this._workletNode = null;\n\n // array of sources so that they can all be stopped!\n this.bufferSourceNodes = [];\n\n // current source\n this.bufferSourceNode = null;\n\n this.buffer = null;\n this.playbackRate = 1;\n\n this.input = p5sound.audiocontext.createGain();\n this.output = p5sound.audiocontext.createGain();\n\n this.reversed = false;\n\n // start and end of playback / loop\n this.startTime = 0;\n this.endTime = null;\n this.pauseTime = 0;\n\n // \"restart\" would stop playback before retriggering\n this.mode = 'sustain';\n\n // time that playback was started, in millis\n this.startMillis = null;\n\n // stereo panning\n this.panPosition = 0.0;\n this.panner = new p5.Panner(this.output, p5sound.input, 2);\n\n // it is possible to instantiate a soundfile with no path\n if (this.url || this.file) {\n this.load(onload, onerror);\n }\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n\n if (typeof whileLoading === 'function') {\n this._whileLoading = whileLoading;\n } else {\n this._whileLoading = function () {};\n }\n\n this._clearOnEnd = _clearOnEnd.bind(this);\n };\n\n // register preload handling of loadSound\n p5.prototype.registerPreloadMethod('loadSound', p5.prototype);\n\n /**\n * loadSound() returns a new p5.SoundFile from a specified\n * path. If called during preload(), the p5.SoundFile will be ready\n * to play in time for setup() and draw(). If called outside of\n * preload, the p5.SoundFile will not be ready immediately, so\n * loadSound accepts a callback as the second parameter. Using a\n * \n * local server is recommended when loading external files.\n *\n * @method loadSound\n * @for p5\n * @param {String|Array} path Path to the sound file, or an array with\n * paths to soundfiles in multiple formats\n * i.e. ['sound.ogg', 'sound.mp3'].\n * Alternately, accepts an object: either\n * from the HTML5 File API, or a p5.File.\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is\n * an error loading the file.\n * @param {Function} [whileLoading] Name of a function to call while file is loading.\n * This function will receive the percentage loaded\n * so far, from 0.0 to 1.0.\n * @return {SoundFile} Returns a p5.SoundFile\n * @example\n *
\n * let mySound;\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * mySound = loadSound('assets/doorbell');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap here to play', 10, 20);\n * }\n *\n * function canvasPressed() {\n * // playing a sound file on a user gesture\n * // is equivalent to `userStartAudio()`\n * mySound.play();\n * }\n *
\n */\n p5.prototype.loadSound = function (path, callback, onerror, whileLoading) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n window.alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n\n var self = this;\n var s = new p5.SoundFile(\n path,\n function () {\n if (typeof callback === 'function') {\n callback.apply(self, arguments);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n },\n onerror,\n whileLoading\n );\n\n return s;\n };\n\n /**\n * This is a helper function that the p5.SoundFile calls to load\n * itself. Accepts a callback (the name of another function)\n * as an optional parameter.\n *\n * @private\n * @for p5.SoundFile\n * @param {Function} [successCallback] Name of a function to call once file loads\n * @param {Function} [errorCallback] Name of a function to call if there is an error\n */\n p5.SoundFile.prototype.load = function (callback, errorCallback) {\n var self = this;\n var errorTrace = new Error().stack;\n\n if (this.url !== undefined && this.url !== '') {\n var request = new XMLHttpRequest();\n request.addEventListener(\n 'progress',\n function (evt) {\n self._updateProgress(evt);\n },\n false\n );\n request.open('GET', this.url, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function () {\n if (request.status === 200) {\n // on sucess loading file:\n if (!self.panner) return;\n ac.decodeAudioData(\n request.response,\n // success decoding buffer:\n function (buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function () {\n if (!self.panner) return;\n var err = new CustomError(\n 'decodeAudioData',\n errorTrace,\n self.url\n );\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n if (!self.panner) return;\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg =\n 'Unable to load ' +\n self.url +\n '. The request status was: ' +\n request.status +\n ' (' +\n request.statusText +\n ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function () {\n var err = new CustomError('loadSound', errorTrace, self.url);\n var msg =\n 'There was no response from the server at ' +\n self.url +\n '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n };\n\n request.send();\n } else if (this.file !== undefined) {\n var reader = new FileReader();\n reader.onload = function () {\n if (!self.panner) return;\n ac.decodeAudioData(reader.result, function (buff) {\n if (!self.panner) return;\n self.buffer = buff;\n self.panner.inputChannels(buff.numberOfChannels);\n if (callback) {\n callback(self);\n }\n });\n };\n reader.onerror = function (e) {\n if (!self.panner) return;\n if (onerror) {\n onerror(e);\n }\n };\n reader.readAsArrayBuffer(this.file);\n }\n };\n\n // TO DO: use this method to create a loading bar that shows progress during file upload/decode.\n p5.SoundFile.prototype._updateProgress = function (evt) {\n if (evt.lengthComputable) {\n var percentComplete = (evt.loaded / evt.total) * 0.99;\n this._whileLoading(percentComplete, evt);\n // ...\n } else {\n // Unable to compute progress information since the total size is unknown\n this._whileLoading('size unknown');\n }\n };\n\n /**\n * Returns true if the sound file finished loading successfully.\n *\n * @method isLoaded\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLoaded = function () {\n if (this.buffer) {\n return true;\n } else {\n return false;\n }\n };\n\n /**\n * Play the p5.SoundFile\n *\n * @method play\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule playback to start (in seconds from now).\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) amplitude (volume)\n * of playback\n * @param {Number} [cueStart] (optional) cue start time in seconds\n * @param {Number} [duration] (optional) duration of playback in seconds\n */\n p5.SoundFile.prototype.play = function (\n startTime,\n rate,\n amp,\n _cueStart,\n duration\n ) {\n if (!this.output) {\n console.warn('SoundFile.play() called after dispose');\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var cueStart, cueEnd;\n var time = startTime || 0;\n if (time < 0) {\n time = 0;\n }\n\n time = time + now;\n\n if (typeof rate !== 'undefined') {\n this.rate(rate);\n }\n\n if (typeof amp !== 'undefined') {\n this.setVolume(amp);\n }\n\n // TO DO: if already playing, create array of buffers for easy stop()\n if (this.buffer) {\n // reset the pause time (if it was paused)\n this._pauseTime = 0;\n\n // handle restart playmode\n if (this.mode === 'restart' && this.buffer && this.bufferSourceNode) {\n this.bufferSourceNode.stop(time);\n this._counterNode.stop(time);\n }\n\n //dont create another instance if already playing\n if (this.mode === 'untildone' && this.isPlaying()) {\n return;\n }\n // make a new source and counter. They are automatically assigned playbackRate and buffer\n this.bufferSourceNode = this._initSourceNode();\n\n // garbage collect counterNode and create a new one\n delete this._counterNode;\n this._counterNode = this._initCounterNode();\n\n if (_cueStart) {\n if (_cueStart >= 0 && _cueStart < this.buffer.duration) {\n // this.startTime = cueStart;\n cueStart = _cueStart;\n } else {\n throw 'start time out of range';\n }\n } else {\n cueStart = 0;\n }\n\n if (duration) {\n // if duration is greater than buffer.duration, just play entire file anyway rather than throw an error\n duration =\n duration <= this.buffer.duration - cueStart\n ? duration\n : this.buffer.duration;\n }\n\n // if it was paused, play at the pause position\n if (this._paused) {\n this.bufferSourceNode.start(time, this.pauseTime, duration);\n this._counterNode.start(time, this.pauseTime, duration);\n } else {\n this.bufferSourceNode.start(time, cueStart, duration);\n this._counterNode.start(time, cueStart, duration);\n }\n\n this._playing = true;\n this._paused = false;\n\n // add source to sources array, which is used in stopAll()\n this.bufferSourceNodes.push(this.bufferSourceNode);\n this.bufferSourceNode._arrayIndex = this.bufferSourceNodes.length - 1;\n\n this.bufferSourceNode.addEventListener('ended', this._clearOnEnd);\n }\n // If soundFile hasn't loaded the buffer yet, throw an error\n else {\n throw 'not ready to play file, buffer has yet to load. Try preload()';\n }\n\n // if looping, will restart at original time\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n\n if (this._looping === true) {\n cueEnd = duration ? duration : cueStart - 0.000000000000001;\n this.bufferSourceNode.loopStart = cueStart;\n this.bufferSourceNode.loopEnd = cueEnd;\n this._counterNode.loopStart = cueStart;\n this._counterNode.loopEnd = cueEnd;\n }\n };\n\n /**\n * p5.SoundFile has two play modes: restart and\n * sustain. Play Mode determines what happens to a\n * p5.SoundFile if it is triggered while in the middle of playback.\n * In sustain mode, playback will continue simultaneous to the\n * new playback. In restart mode, play() will stop playback\n * and start over. With untilDone, a sound will play only if it's\n * not already playing. Sustain is the default mode.\n *\n * @method playMode\n * @for p5.SoundFile\n * @param {String} str 'restart' or 'sustain' or 'untilDone'\n * @example\n *
\n * let mySound;\n * function preload(){\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * noFill();\n * rect(0, height/2, width - 1, height/2 - 1);\n * rect(0, 0, width - 1, height/2);\n * textAlign(CENTER, CENTER);\n * fill(20);\n * text('restart', width/2, 1 * height/4);\n * text('sustain', width/2, 3 * height/4);\n * }\n * function canvasPressed() {\n * if (mouseX < height/2) {\n * mySound.playMode('restart');\n * } else {\n * mySound.playMode('sustain');\n * }\n * mySound.play();\n * }\n *\n *
\n */\n p5.SoundFile.prototype.playMode = function (str) {\n var s = str.toLowerCase();\n\n // if restart, stop all other sounds from playing\n if (s === 'restart' && this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNodes[i].stop(now);\n }\n }\n\n // set play mode to effect future playback\n if (s === 'restart' || s === 'sustain' || s === 'untildone') {\n this.mode = s;\n } else {\n throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n }\n };\n\n /**\n * Pauses a file that is currently playing. If the file is not\n * playing, then nothing will happen.\n *\n * After pausing, .play() will resume from the paused\n * position.\n * If p5.SoundFile had been set to loop before it was paused,\n * it will continue to loop after it is unpaused with .play().\n *\n * @method pause\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @example\n *
\n * let soundFile;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.pause = function (startTime) {\n var now = p5sound.audiocontext.currentTime;\n var time = startTime || 0;\n var pTime = time + now;\n\n if (this.isPlaying() && this.buffer && this.bufferSourceNode) {\n this._paused = true;\n this._playing = false;\n\n this.pauseTime = this.currentTime();\n this.bufferSourceNode.stop(pTime);\n this._counterNode.stop(pTime);\n\n this._pauseTime = this.currentTime();\n // TO DO: make sure play() still starts from orig start position\n } else {\n this._pauseTime = 0;\n }\n };\n\n /**\n * Loop the p5.SoundFile. Accepts optional parameters to set the\n * playback rate, playback volume, loopStart, loopEnd.\n *\n * @method loop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * seconds from now\n * @param {Number} [rate] (optional) playback rate\n * @param {Number} [amp] (optional) playback volume\n * @param {Number} [cueLoopStart] (optional) startTime in seconds\n * @param {Number} [duration] (optional) loop duration in seconds\n * @example\n *
\n * let soundFile;\n * let loopStart = 0.5;\n * let loopDuration = 0.2;\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play, release to pause', 10, 20, width - 20);\n * }\n * function canvasPressed() {\n * soundFile.loop();\n * background(0, 200, 50);\n * }\n * function mouseReleased() {\n * soundFile.pause();\n * background(220);\n * }\n * \n *
\n */\n p5.SoundFile.prototype.loop = function (\n startTime,\n rate,\n amp,\n loopStart,\n duration\n ) {\n this._looping = true;\n this.play(startTime, rate, amp, loopStart, duration);\n };\n\n /**\n * Set a p5.SoundFile's looping flag to true or false. If the sound\n * is currently playing, this change will take effect when it\n * reaches the end of the current playback.\n *\n * @method setLoop\n * @for p5.SoundFile\n * @param {Boolean} Boolean set looping to true or false\n */\n p5.SoundFile.prototype.setLoop = function (bool) {\n if (bool === true) {\n this._looping = true;\n } else if (bool === false) {\n this._looping = false;\n } else {\n throw 'Error: setLoop accepts either true or false';\n }\n if (this.bufferSourceNode) {\n this.bufferSourceNode.loop = this._looping;\n this._counterNode.loop = this._looping;\n }\n };\n\n /**\n * Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.\n *\n * @method isLooping\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isLooping = function () {\n if (!this.bufferSourceNode) {\n return false;\n }\n if (this._looping === true && this.isPlaying() === true) {\n return true;\n }\n return false;\n };\n\n /**\n * Returns true if a p5.SoundFile is playing, false if not (i.e.\n * paused or stopped).\n *\n * @method isPlaying\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPlaying = function () {\n return this._playing;\n };\n\n /**\n * Returns true if a p5.SoundFile is paused, false if not (i.e.\n * playing or stopped).\n *\n * @method isPaused\n * @for p5.SoundFile\n * @return {Boolean}\n */\n p5.SoundFile.prototype.isPaused = function () {\n return this._paused;\n };\n\n /**\n * Stop soundfile playback.\n *\n * @method stop\n * @for p5.SoundFile\n * @param {Number} [startTime] (optional) schedule event to occur\n * in seconds from now\n */\n p5.SoundFile.prototype.stop = function (timeFromNow) {\n var time = timeFromNow || 0;\n\n if (this.mode === 'sustain' || this.mode === 'untildone') {\n this.stopAll(time);\n this._playing = false;\n this.pauseTime = 0;\n this._paused = false;\n } else if (this.buffer && this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n this.pauseTime = 0;\n this.bufferSourceNode.stop(now + t);\n this._counterNode.stop(now + t);\n this._playing = false;\n this._paused = false;\n }\n };\n\n /**\n * Stop playback on all of this soundfile's sources.\n * @private\n */\n p5.SoundFile.prototype.stopAll = function (_time) {\n var now = p5sound.audiocontext.currentTime;\n var time = _time || 0;\n if (this.buffer && this.bufferSourceNode) {\n for (var i in this.bufferSourceNodes) {\n const bufferSourceNode = this.bufferSourceNodes[i];\n if (bufferSourceNode) {\n try {\n bufferSourceNode.stop(now + time);\n } catch (e) {\n // this was throwing errors only on Safari\n }\n }\n }\n this._counterNode.stop(now + time);\n this._onended(this);\n }\n };\n\n /**\n * Multiply the output volume (amplitude) of a sound file\n * between 0.0 (silence) and 1.0 (full volume).\n * 1.0 is the maximum amplitude of a digital sound, so multiplying\n * by greater than 1.0 may cause digital distortion. To\n * fade, provide a rampTime parameter. For more\n * complex fades, see the Envelope class.\n *\n * Alternately, you can pass in a signal source such as an\n * oscillator to modulate the amplitude with an audio signal.\n *\n * @method setVolume\n * @for p5.SoundFile\n * @param {Number|Object} volume Volume (amplitude) between 0.0\n * and 1.0 or modulating signal/oscillator\n * @param {Number} [rampTime] Fade for t seconds\n * @param {Number} [timeFromNow] Schedule this event to happen at\n * t seconds in the future\n */\n p5.SoundFile.prototype.setVolume = function (vol, _rampTime, _tFromNow) {\n if (typeof vol === 'number') {\n var rampTime = _rampTime || 0;\n var tFromNow = _tFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now + tFromNow);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n } else if (vol) {\n vol.connect(this.output.gain);\n } else {\n // return the Gain Node\n return this.output.gain;\n }\n };\n\n // same as setVolume, to match Processing Sound\n p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n\n // these are the same thing\n p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n\n p5.SoundFile.prototype.getVolume = function () {\n return this.output.gain.value;\n };\n\n /**\n * Set the stereo panning of a p5.sound object to\n * a floating point number between -1.0 (left) and 1.0 (right).\n * Default is 0.0 (center).\n *\n * @method pan\n * @for p5.SoundFile\n * @param {Number} [panValue] Set the stereo panner\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n * @example\n *
\n * let ballX = 0;\n * let soundFile;\n *\n * function preload() {\n * soundFormats('ogg', 'mp3');\n * soundFile = loadSound('assets/beatbox.mp3');\n * }\n *\n * function draw() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * ballX = constrain(mouseX, 0, width);\n * ellipse(ballX, height/2, 20, 20);\n * }\n *\n * function canvasPressed(){\n * // map the ball's x location to a panning degree\n * // between -1.0 (left) and 1.0 (right)\n * let panning = map(ballX, 0., width,-1.0, 1.0);\n * soundFile.pan(panning);\n * soundFile.play();\n * }\n *
\n */\n p5.SoundFile.prototype.pan = function (pval, tFromNow) {\n this.panPosition = pval;\n this.panner.pan(pval, tFromNow);\n };\n\n /**\n * Returns the current stereo pan position (-1.0 to 1.0)\n *\n * @method getPan\n * @for p5.SoundFile\n * @return {Number} Returns the stereo pan setting of the Oscillator\n * as a number between -1.0 (left) and 1.0 (right).\n * 0.0 is center and default.\n */\n p5.SoundFile.prototype.getPan = function () {\n return this.panPosition;\n };\n\n /**\n * Set the playback rate of a sound file. Will change the speed and the pitch.\n * Values less than zero will reverse the audio buffer.\n *\n * @method rate\n * @for p5.SoundFile\n * @param {Number} [playbackRate] Set the playback rate. 1.0 is normal,\n * .5 is half-speed, 2.0 is twice as fast.\n * Values less than zero play backwards.\n * @example\n *
\n * let mySound;\n *\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * }\n * function canvasPressed() {\n * mySound.loop();\n * }\n * function mouseReleased() {\n * mySound.pause();\n * }\n * function draw() {\n * background(220);\n *\n * // Set the rate to a range between 0.1 and 4\n * // Changing the rate also alters the pitch\n * let playbackRate = map(mouseY, 0.1, height, 2, 0);\n * playbackRate = constrain(playbackRate, 0.01, 4);\n * mySound.rate(playbackRate);\n *\n * line(0, mouseY, width, mouseY);\n * text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n * }\n *\n * \n *
\n *\n */\n p5.SoundFile.prototype.rate = function (playbackRate) {\n var reverse = false;\n if (typeof playbackRate === 'undefined') {\n return this.playbackRate;\n }\n\n this.playbackRate = playbackRate;\n\n if (playbackRate === 0) {\n playbackRate = 0.0000000000001;\n } else if (playbackRate < 0 && !this.reversed) {\n playbackRate = Math.abs(playbackRate);\n reverse = true;\n } else if (playbackRate > 0 && this.reversed) {\n reverse = true;\n }\n\n if (this.bufferSourceNode) {\n var now = p5sound.audiocontext.currentTime;\n this.bufferSourceNode.playbackRate.cancelScheduledValues(now);\n this.bufferSourceNode.playbackRate.linearRampToValueAtTime(\n Math.abs(playbackRate),\n now\n );\n this._counterNode.playbackRate.cancelScheduledValues(now);\n this._counterNode.playbackRate.linearRampToValueAtTime(\n Math.abs(playbackRate),\n now\n );\n }\n\n if (reverse) {\n this.reverseBuffer();\n }\n return this.playbackRate;\n };\n\n // TO DO: document this\n p5.SoundFile.prototype.setPitch = function (num) {\n var newPlaybackRate = midiToFreq(num) / midiToFreq(60);\n this.rate(newPlaybackRate);\n };\n\n p5.SoundFile.prototype.getPlaybackRate = function () {\n return this.playbackRate;\n };\n\n /**\n * Returns the duration of a sound file in seconds.\n *\n * @method duration\n * @for p5.SoundFile\n * @return {Number} The duration of the soundFile in seconds.\n */\n p5.SoundFile.prototype.duration = function () {\n // Return Duration\n if (this.buffer) {\n return this.buffer.duration;\n } else {\n return 0;\n }\n };\n\n /**\n * Return the current position of the p5.SoundFile playhead, in seconds.\n * Time is relative to the normal buffer direction, so if `reverseBuffer`\n * has been called, currentTime will count backwards.\n *\n * @method currentTime\n * @for p5.SoundFile\n * @return {Number} currentTime of the soundFile in seconds.\n */\n p5.SoundFile.prototype.currentTime = function () {\n return this.reversed\n ? Math.abs(this._lastPos - this.buffer.length) / ac.sampleRate\n : this._lastPos / ac.sampleRate;\n };\n\n /**\n * Move the playhead of a soundfile that is currently playing to a\n * new position and a new duration, in seconds.\n * If none are given, will reset the file to play entire duration\n * from start to finish. To set the position of a soundfile that is\n * not currently playing, use the `play` or `loop` methods.\n *\n * @method jump\n * @for p5.SoundFile\n * @param {Number} cueTime cueTime of the soundFile in seconds.\n * @param {Number} duration duration in seconds.\n */\n p5.SoundFile.prototype.jump = function (cueTime, duration) {\n if (cueTime < 0 || cueTime > this.buffer.duration) {\n throw 'jump time out of range';\n }\n if (duration > this.buffer.duration - cueTime) {\n throw 'end time out of range';\n }\n\n var cTime = cueTime || 0;\n var dur = duration || undefined;\n if (this.isPlaying()) {\n this.stop(0);\n this.play(0, this.playbackRate, this.output.gain.value, cTime, dur);\n }\n };\n\n /**\n * Return the number of channels in a sound file.\n * For example, Mono = 1, Stereo = 2.\n *\n * @method channels\n * @for p5.SoundFile\n * @return {Number} [channels]\n */\n p5.SoundFile.prototype.channels = function () {\n return this.buffer.numberOfChannels;\n };\n\n /**\n * Return the sample rate of the sound file.\n *\n * @method sampleRate\n * @for p5.SoundFile\n * @return {Number} [sampleRate]\n */\n p5.SoundFile.prototype.sampleRate = function () {\n return this.buffer.sampleRate;\n };\n\n /**\n * Return the number of samples in a sound file.\n * Equal to sampleRate * duration.\n *\n * @method frames\n * @for p5.SoundFile\n * @return {Number} [sampleCount]\n */\n p5.SoundFile.prototype.frames = function () {\n return this.buffer.length;\n };\n\n /**\n * Returns an array of amplitude peaks in a p5.SoundFile that can be\n * used to draw a static waveform. Scans through the p5.SoundFile's\n * audio buffer to find the greatest amplitudes. Accepts one\n * parameter, 'length', which determines size of the array.\n * Larger arrays result in more precise waveform visualizations.\n *\n * Inspired by Wavesurfer.js.\n *\n * @method getPeaks\n * @for p5.SoundFile\n * @params {Number} [length] length is the size of the returned array.\n * Larger length results in more precision.\n * Defaults to 5*width of the browser window.\n * @returns {Float32Array} Array of peaks.\n */\n p5.SoundFile.prototype.getPeaks = function (length) {\n if (this.buffer) {\n // set length to window's width if no length is provided\n if (!length) {\n length = window.width * 5;\n }\n if (this.buffer) {\n var buffer = this.buffer;\n var sampleSize = buffer.length / length;\n var sampleStep = ~~(sampleSize / 10) || 1;\n var channels = buffer.numberOfChannels;\n var peaks = new Float32Array(Math.round(length));\n\n for (var c = 0; c < channels; c++) {\n var chan = buffer.getChannelData(c);\n for (var i = 0; i < length; i++) {\n var start = ~~(i * sampleSize);\n var end = ~~(start + sampleSize);\n var max = 0;\n for (var j = start; j < end; j += sampleStep) {\n var value = chan[j];\n if (value > max) {\n max = value;\n // faster than Math.abs\n } else if (-value > max) {\n max = value;\n }\n }\n if (c === 0 || Math.abs(max) > peaks[i]) {\n peaks[i] = max;\n }\n }\n }\n\n return peaks;\n }\n } else {\n throw 'Cannot load peaks yet, buffer is not loaded';\n }\n };\n\n /**\n * Reverses the p5.SoundFile's buffer source.\n * Playback must be handled separately (see example).\n *\n * @method reverseBuffer\n * @for p5.SoundFile\n * @example\n *
\n * let drum;\n * function preload() {\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n * }\n *\n * function canvasPressed() {\n * drum.stop();\n * drum.reverseBuffer();\n * drum.play();\n * }\n * \n *
\n */\n p5.SoundFile.prototype.reverseBuffer = function () {\n if (this.buffer) {\n var currentPos = this._lastPos / ac.sampleRate;\n var curVol = this.getVolume();\n this.setVolume(0, 0.001);\n\n const numChannels = this.buffer.numberOfChannels;\n for (var i = 0; i < numChannels; i++) {\n this.buffer.getChannelData(i).reverse();\n }\n // set reversed flag\n this.reversed = !this.reversed;\n\n if (this.isPlaying() && currentPos) {\n this.jump(this.duration() - currentPos);\n }\n this.setVolume(curVol, 0.001);\n } else {\n throw 'SoundFile is not done loading';\n }\n };\n\n /**\n * Schedule an event to be called when the soundfile\n * reaches the end of a buffer. If the soundfile is\n * playing through once, this will be called when it\n * ends. If it is looping, it will be called when\n * stop is called.\n *\n * @method onended\n * @for p5.SoundFile\n * @param {Function} callback function to call when the\n * soundfile has ended.\n */\n p5.SoundFile.prototype.onended = function (callback) {\n this._onended = callback;\n return this;\n };\n\n p5.SoundFile.prototype.add = function () {\n // TO DO\n };\n\n p5.SoundFile.prototype.dispose = function () {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference to soundfile\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop(now);\n if (this.buffer && this.bufferSourceNode) {\n for (var i = 0; i < this.bufferSourceNodes.length - 1; i++) {\n if (this.bufferSourceNodes[i] !== null) {\n this.bufferSourceNodes[i].disconnect();\n try {\n this.bufferSourceNodes[i].stop(now);\n } catch (e) {\n console.warn('no buffer source node to dispose');\n }\n this.bufferSourceNodes[i] = null;\n }\n }\n if (this.isPlaying()) {\n try {\n this._counterNode.stop(now);\n } catch (e) {\n console.log(e);\n }\n this._counterNode = null;\n }\n }\n if (this.output) {\n this.output.disconnect();\n this.output = null;\n }\n if (this.panner) {\n this.panner.disconnect();\n this.panner = null;\n }\n };\n\n /**\n * Connects the output of a p5sound object to input of another\n * p5.sound object. For example, you may connect a p5.SoundFile to an\n * FFT or an Effect. If no parameter is given, it will connect to\n * the master output. Most p5sound objects connect to the master\n * output when they are created.\n *\n * @method connect\n * @for p5.SoundFile\n * @param {Object} [object] Audio object that accepts an input\n */\n p5.SoundFile.prototype.connect = function (unit) {\n if (!unit) {\n this.panner.connect(p5sound.input);\n } else {\n if (unit.hasOwnProperty('input')) {\n this.panner.connect(unit.input);\n } else {\n this.panner.connect(unit);\n }\n }\n };\n\n /**\n * Disconnects the output of this p5sound object.\n *\n * @method disconnect\n * @for p5.SoundFile\n */\n p5.SoundFile.prototype.disconnect = function () {\n if (this.panner) {\n this.panner.disconnect();\n }\n };\n\n /**\n */\n p5.SoundFile.prototype.getLevel = function () {\n console.warn(\n 'p5.SoundFile.getLevel has been removed from the library. Use p5.Amplitude instead'\n );\n };\n\n /**\n * Reset the source for this SoundFile to a\n * new path (URL).\n *\n * @method setPath\n * @for p5.SoundFile\n * @param {String} path path to audio file\n * @param {Function} callback Callback\n */\n p5.SoundFile.prototype.setPath = function (p, callback) {\n var path = p5.prototype._checkFileFormats(p);\n this.url = path;\n this.load(callback);\n };\n\n /**\n * Replace the current Audio Buffer with a new Buffer.\n *\n * @method setBuffer\n * @for p5.SoundFile\n * @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n * will create a stereo source. 1 will create\n * a mono source.\n */\n p5.SoundFile.prototype.setBuffer = function (buf) {\n var numChannels = buf.length;\n var size = buf[0].length;\n var newBuffer = ac.createBuffer(numChannels, size, ac.sampleRate);\n\n if (!(buf[0] instanceof Float32Array)) {\n buf[0] = new Float32Array(buf[0]);\n }\n\n for (var channelNum = 0; channelNum < numChannels; channelNum++) {\n var channel = newBuffer.getChannelData(channelNum);\n channel.set(buf[channelNum]);\n }\n\n this.buffer = newBuffer;\n\n // set numbers of channels on input to the panner\n this.panner.inputChannels(numChannels);\n };\n\n //////////////////////////////////////////////////\n // script processor node with an empty buffer to help\n // keep a sample-accurate position in playback buffer.\n // Inspired by Chinmay Pendharkar's technique for Sonoport --> http://bit.ly/1HwdCsV\n // Copyright [2015] [Sonoport (Asia) Pte. Ltd.],\n // Licensed under the Apache License http://apache.org/licenses/LICENSE-2.0\n ////////////////////////////////////////////////////////////////////////////////////\n\n var _createCounterBuffer = function (buffer) {\n const len = buffer.length;\n const audioBuf = ac.createBuffer(1, buffer.length, ac.sampleRate);\n const arrayBuffer = audioBuf.getChannelData(0);\n for (var index = 0; index < len; index++) {\n arrayBuffer[index] = index;\n }\n return audioBuf;\n };\n\n // initialize counterNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initCounterNode = function () {\n var self = this;\n var now = ac.currentTime;\n var cNode = ac.createBufferSource();\n\n const workletBufferSize = safeBufferSize(256);\n\n // dispose of worklet node if it already exists\n if (self._workletNode) {\n self._workletNode.disconnect();\n delete self._workletNode;\n }\n self._workletNode = new AudioWorkletNode(\n ac,\n processorNames.soundFileProcessor,\n {\n processorOptions: { bufferSize: workletBufferSize },\n }\n );\n self._workletNode.port.onmessage = (event) => {\n if (event.data.name === 'position') {\n // event.data.position should only be 0 when paused\n if (event.data.position === 0) {\n return;\n }\n this._lastPos = event.data.position;\n\n // do any callbacks that have been scheduled\n this._onTimeUpdate(self._lastPos);\n }\n };\n\n // create counter buffer of the same length as self.buffer\n cNode.buffer = _createCounterBuffer(self.buffer);\n\n cNode.playbackRate.setValueAtTime(self.playbackRate, now);\n\n cNode.connect(self._workletNode);\n self._workletNode.connect(p5.soundOut._silentNode);\n\n return cNode;\n };\n\n // initialize sourceNode, set its initial buffer and playbackRate\n p5.SoundFile.prototype._initSourceNode = function () {\n var bufferSourceNode = ac.createBufferSource();\n bufferSourceNode.buffer = this.buffer;\n bufferSourceNode.playbackRate.value = this.playbackRate;\n bufferSourceNode.connect(this.output);\n return bufferSourceNode;\n };\n\n /**\n * processPeaks returns an array of timestamps where it thinks there is a beat.\n *\n * This is an asynchronous function that processes the soundfile in an offline audio context,\n * and sends the results to your callback function.\n *\n * The process involves running the soundfile through a lowpass filter, and finding all of the\n * peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks,\n * it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached.\n *\n * @method processPeaks\n * @for p5.SoundFile\n * @param {Function} callback a function to call once this data is returned\n * @param {Number} [initThreshold] initial threshold defaults to 0.9\n * @param {Number} [minThreshold] minimum threshold defaults to 0.22\n * @param {Number} [minPeaks] minimum number of peaks defaults to 200\n * @return {Array} Array of timestamped peaks\n */\n p5.SoundFile.prototype.processPeaks = function (\n callback,\n _initThreshold,\n _minThreshold,\n _minPeaks\n ) {\n var bufLen = this.buffer.length;\n var sampleRate = this.buffer.sampleRate;\n var buffer = this.buffer;\n var allPeaks = [];\n\n var initialThreshold = _initThreshold || 0.9,\n threshold = initialThreshold,\n minThreshold = _minThreshold || 0.22,\n minPeaks = _minPeaks || 200;\n\n // Create offline context\n var offlineContext = new window.OfflineAudioContext(1, bufLen, sampleRate);\n\n // create buffer source\n var source = offlineContext.createBufferSource();\n source.buffer = buffer;\n\n // Create filter. TO DO: allow custom setting of filter\n var filter = offlineContext.createBiquadFilter();\n filter.type = 'lowpass';\n source.connect(filter);\n filter.connect(offlineContext.destination);\n\n // start playing at time:0\n source.start(0);\n offlineContext.startRendering(); // Render the song\n\n // act on the result\n offlineContext.oncomplete = function (e) {\n if (!self.panner) return;\n var filteredBuffer = e.renderedBuffer;\n var bufferData = filteredBuffer.getChannelData(0);\n\n // step 1:\n // create Peak instances, add them to array, with strength and sampleIndex\n do {\n allPeaks = getPeaksAtThreshold(bufferData, threshold);\n threshold -= 0.005;\n } while (\n Object.keys(allPeaks).length < minPeaks &&\n threshold >= minThreshold\n );\n\n // step 2:\n // find intervals for each peak in the sampleIndex, add tempos array\n var intervalCounts = countIntervalsBetweenNearbyPeaks(allPeaks);\n\n // step 3: find top tempos\n var groups = groupNeighborsByTempo(\n intervalCounts,\n filteredBuffer.sampleRate\n );\n\n // sort top intervals\n var topTempos = groups\n .sort(function (intA, intB) {\n return intB.count - intA.count;\n })\n .splice(0, 5);\n\n // set this SoundFile's tempo to the top tempo ??\n this.tempo = topTempos[0].tempo;\n\n // step 4:\n // new array of peaks at top tempo within a bpmVariance\n var bpmVariance = 5;\n var tempoPeaks = getPeaksAtTopTempo(\n allPeaks,\n topTempos[0].tempo,\n filteredBuffer.sampleRate,\n bpmVariance\n );\n\n callback(tempoPeaks);\n };\n };\n\n // process peaks\n var Peak = function (amp, i) {\n this.sampleIndex = i;\n this.amplitude = amp;\n this.tempos = [];\n this.intervals = [];\n };\n\n // 1. for processPeaks() Function to identify peaks above a threshold\n // returns an array of peak indexes as frames (samples) of the original soundfile\n function getPeaksAtThreshold(data, threshold) {\n var peaksObj = {};\n var length = data.length;\n\n for (var i = 0; i < length; i++) {\n if (data[i] > threshold) {\n var amp = data[i];\n var peak = new Peak(amp, i);\n peaksObj[i] = peak;\n // Skip forward ~ 1/8s to get past this peak.\n i += 6000;\n }\n i++;\n }\n return peaksObj;\n }\n\n // 2. for processPeaks()\n function countIntervalsBetweenNearbyPeaks(peaksObj) {\n var intervalCounts = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n for (var index = 0; index < peaksArray.length; index++) {\n // find intervals in comparison to nearby peaks\n for (var i = 0; i < 10; i++) {\n var startPeak = peaksObj[peaksArray[index]];\n var endPeak = peaksObj[peaksArray[index + i]];\n\n if (startPeak && endPeak) {\n var startPos = startPeak.sampleIndex;\n var endPos = endPeak.sampleIndex;\n var interval = endPos - startPos;\n\n // add a sample interval to the startPeak in the allPeaks array\n if (interval > 0) {\n startPeak.intervals.push(interval);\n }\n\n // tally the intervals and return interval counts\n var foundInterval = intervalCounts.some(function (intervalCount) {\n if (intervalCount.interval === interval) {\n intervalCount.count++;\n return intervalCount;\n }\n });\n\n // store with JSON like formatting\n if (!foundInterval) {\n intervalCounts.push({\n interval: interval,\n count: 1,\n });\n }\n }\n }\n }\n\n return intervalCounts;\n }\n\n // 3. for processPeaks --> find tempo\n function groupNeighborsByTempo(intervalCounts, sampleRate) {\n var tempoCounts = [];\n\n intervalCounts.forEach(function (intervalCount) {\n try {\n // Convert an interval to tempo\n var theoreticalTempo = Math.abs(\n 60 / (intervalCount.interval / sampleRate)\n );\n\n theoreticalTempo = mapTempo(theoreticalTempo);\n\n var foundTempo = tempoCounts.some(function (tempoCount) {\n if (tempoCount.tempo === theoreticalTempo)\n return (tempoCount.count += intervalCount.count);\n });\n if (!foundTempo) {\n if (isNaN(theoreticalTempo)) {\n return;\n }\n tempoCounts.push({\n tempo: Math.round(theoreticalTempo),\n count: intervalCount.count,\n });\n }\n } catch (e) {\n throw e;\n }\n });\n\n return tempoCounts;\n }\n\n // 4. for processPeaks - get peaks at top tempo\n function getPeaksAtTopTempo(peaksObj, tempo, sampleRate, bpmVariance) {\n var peaksAtTopTempo = [];\n var peaksArray = Object.keys(peaksObj).sort();\n\n // TO DO: filter out peaks that have the tempo and return\n for (var i = 0; i < peaksArray.length; i++) {\n var key = peaksArray[i];\n var peak = peaksObj[key];\n\n for (var j = 0; j < peak.intervals.length; j++) {\n var intervalBPM = Math.round(\n Math.abs(60 / (peak.intervals[j] / sampleRate))\n );\n\n intervalBPM = mapTempo(intervalBPM);\n\n if (Math.abs(intervalBPM - tempo) < bpmVariance) {\n // convert sampleIndex to seconds\n peaksAtTopTempo.push(peak.sampleIndex / sampleRate);\n }\n }\n }\n\n // filter out peaks that are very close to each other\n peaksAtTopTempo = peaksAtTopTempo.filter(function (peakTime, index, arr) {\n var dif = arr[index + 1] - peakTime;\n if (dif > 0.01) {\n return true;\n }\n });\n\n return peaksAtTopTempo;\n }\n\n // helper function for processPeaks\n function mapTempo(theoreticalTempo) {\n // these scenarios create infinite while loop\n if (!isFinite(theoreticalTempo) || theoreticalTempo === 0) {\n return;\n }\n\n // Adjust the tempo to fit within the 90-180 BPM range\n while (theoreticalTempo < 90) theoreticalTempo *= 2;\n while (theoreticalTempo > 180 && theoreticalTempo > 90)\n theoreticalTempo /= 2;\n\n return theoreticalTempo;\n }\n\n /*** SCHEDULE EVENTS ***/\n\n // Cue inspired by JavaScript setTimeout, and the\n // Tone.js Transport Timeline Event, MIT License Yotam Mann 2015 tonejs.org\n var Cue = function (callback, time, id, val) {\n this.callback = callback;\n this.time = time;\n this.id = id;\n this.val = val;\n };\n\n /**\n * Schedule events to trigger every time a MediaElement\n * (audio/video) reaches a playback cue point.\n *\n * Accepts a callback function, a time (in seconds) at which to trigger\n * the callback, and an optional parameter for the callback.\n *\n * Time will be passed as the first parameter to the callback function,\n * and param will be the second parameter.\n *\n *\n * @method addCue\n * @for p5.SoundFile\n * @param {Number} time Time in seconds, relative to this media\n * element's playback. For example, to trigger\n * an event every time playback reaches two\n * seconds, pass in the number 2. This will be\n * passed as the first parameter to\n * the callback function.\n * @param {Function} callback Name of a function that will be\n * called at the given time. The callback will\n * receive time and (optionally) param as its\n * two parameters.\n * @param {Object} [value] An object to be passed as the\n * second parameter to the\n * callback function.\n * @return {Number} id ID of this cue,\n * useful for removeCue(id)\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 10, 20);\n *\n * // schedule calls to changeText\n * mySound.addCue(0, changeText, \"hello\" );\n * mySound.addCue(0.5, changeText, \"hello,\" );\n * mySound.addCue(1, changeText, \"hello, p5!\");\n * mySound.addCue(1.5, changeText, \"hello, p5!!\");\n * mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n * }\n *\n * function changeText(val) {\n * background(220);\n * text(val, 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.play();\n * }\n *
\n */\n p5.SoundFile.prototype.addCue = function (time, callback, val) {\n var id = this._cueIDCounter++;\n\n var cue = new Cue(callback, time, id, val);\n this._cues.push(cue);\n\n // if (!this.elt.ontimeupdate) {\n // this.elt.ontimeupdate = this._onTimeUpdate.bind(this);\n // }\n\n return id;\n };\n\n /**\n * Remove a callback based on its ID. The ID is returned by the\n * addCue method.\n *\n * @method removeCue\n * @for p5.SoundFile\n * @param {Number} id ID of the cue, as returned by addCue\n */\n p5.SoundFile.prototype.removeCue = function (id) {\n var cueLength = this._cues.length;\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n if (cue.id === id) {\n this._cues.splice(i, 1);\n break;\n }\n }\n\n if (this._cues.length === 0) {\n // TO DO: remove callback\n // this.elt.ontimeupdate = null\n }\n };\n\n /**\n * Remove all of the callbacks that had originally been scheduled\n * via the addCue method.\n *\n * @method clearCues\n */\n p5.SoundFile.prototype.clearCues = function () {\n this._cues = [];\n // this.elt.ontimeupdate = null;\n };\n\n // private method that checks for cues to be fired if events\n // have been scheduled using addCue(callback, time).\n p5.SoundFile.prototype._onTimeUpdate = function (position) {\n var playbackTime = position / this.buffer.sampleRate;\n var cueLength = this._cues.length;\n\n for (var i = 0; i < cueLength; i++) {\n var cue = this._cues[i];\n var callbackTime = cue.time;\n var val = cue.val;\n\n if (\n ~~this._prevUpdateTime <= callbackTime &&\n callbackTime <= playbackTime\n ) {\n // pass the scheduled callbackTime as parameter to the callback\n cue.callback(val);\n }\n }\n\n this._prevUpdateTime = playbackTime;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device. To upload a file to a server, see\n * getBlob\n *\n * @method save\n * @for p5.SoundFile\n * @param {String} [fileName] name of the resulting .wav file.\n * @example\n *
\n * let mySound;\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to download', 10, 20);\n * }\n *\n * function canvasPressed() {\n * mySound.save('my cool filename');\n * }\n *
\n */\n p5.SoundFile.prototype.save = function (fileName) {\n p5.prototype.saveSound(this, fileName, 'wav');\n };\n\n /**\n * This method is useful for sending a SoundFile to a server. It returns the\n * .wav-encoded audio data as a \"Blob\".\n * A Blob is a file-like data object that can be uploaded to a server\n * with an http request. We'll\n * use the `httpDo` options object to send a POST request with some\n * specific options: we encode the request as `multipart/form-data`,\n * and attach the blob as one of the form values using `FormData`.\n *\n *\n * @method getBlob\n * @for p5.SoundFile\n * @returns {Blob} A file-like data object\n * @example\n *
\n * function preload() {\n * mySound = loadSound('assets/doorbell.mp3');\n * }\n *\n * function setup() {\n * noCanvas();\n * let soundBlob = mySound.getBlob();\n *\n * // Now we can send the blob to a server...\n * let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n * let httpRequestOptions = {\n * method: 'POST',\n * body: new FormData().append('soundBlob', soundBlob),\n * headers: new Headers({\n * 'Content-Type': 'multipart/form-data'\n * })\n * };\n * httpDo(serverUrl, httpRequestOptions);\n *\n * // We can also create an `ObjectURL` pointing to the Blob\n * let blobUrl = URL.createObjectURL(soundBlob);\n *\n * // The `
\n */\n p5.SoundFile.prototype.getBlob = function () {\n const dataView = convertToWav(this.buffer);\n return new Blob([dataView], { type: 'audio/wav' });\n };\n\n // event handler to remove references to the bufferSourceNode when it is done playing\n function _clearOnEnd(e) {\n const thisBufferSourceNode = e.target;\n const soundFile = this;\n\n // delete this.bufferSourceNode from the sources array when it is done playing:\n thisBufferSourceNode._playing = false;\n thisBufferSourceNode.removeEventListener('ended', soundFile._clearOnEnd);\n\n // call the onended callback\n soundFile._onended(soundFile);\n\n // delete bufferSourceNode(s) in soundFile.bufferSourceNodes\n // iterate in reverse order because the index changes by splice\n soundFile.bufferSourceNodes\n .map((_, i) => i)\n .reverse()\n .forEach(function (i) {\n const n = soundFile.bufferSourceNodes[i];\n\n if (n._playing === false) {\n soundFile.bufferSourceNodes.splice(i, 1);\n }\n });\n\n if (soundFile.bufferSourceNodes.length === 0) {\n soundFile._playing = false;\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n const p5sound = require('master');\n const { safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n\n /**\n * Amplitude measures volume between 0.0 and 1.0.\n * Listens to all p5sound by default, or use setInput()\n * to listen to a specific sound source. Accepts an optional\n * smoothing value, which defaults to 0.\n *\n * @class p5.Amplitude\n * @constructor\n * @param {Number} [smoothing] between 0.0 and .999 to smooth\n * amplitude readings (defaults to 0)\n * @example\n *
\n * let sound, amplitude;\n *\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n * function setup() {\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound() {\n * if (sound.isPlaying() ){\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *\n *
\n */\n p5.Amplitude = function (smoothing) {\n // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n this.bufferSize = safeBufferSize(2048);\n\n // set audio context\n this.audiocontext = p5sound.audiocontext;\n this._workletNode = new AudioWorkletNode(\n this.audiocontext,\n processorNames.amplitudeProcessor,\n {\n outputChannelCount: [1],\n\n parameterData: { smoothing: smoothing || 0 },\n processorOptions: {\n normalize: false,\n smoothing: smoothing || 0,\n numInputChannels: 2,\n bufferSize: this.bufferSize,\n },\n }\n );\n\n this._workletNode.port.onmessage = function (event) {\n if (event.data.name === 'amplitude') {\n this.volume = event.data.volume;\n this.volNorm = event.data.volNorm;\n this.stereoVol = event.data.stereoVol;\n this.stereoVolNorm = event.data.stereoVolNorm;\n }\n }.bind(this);\n\n // for connections\n this.input = this._workletNode;\n\n this.output = this.audiocontext.createGain();\n\n // the variables to return\n this.volume = 0;\n this.volNorm = 0;\n this.stereoVol = [0, 0];\n this.stereoVolNorm = [0, 0];\n\n this.normalize = false;\n\n this._workletNode.connect(this.output);\n this.output.gain.value = 0;\n\n // this may only be necessary because of a Chrome bug\n this.output.connect(this.audiocontext.destination);\n\n // connect to p5sound master output by default, unless set by input()\n p5sound.meter.connect(this._workletNode);\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connects to the p5sound instance (master output) by default.\n * Optionally, you can pass in a specific source (i.e. a soundfile).\n *\n * @method setInput\n * @for p5.Amplitude\n * @param {soundObject|undefined} [snd] set the sound source\n * (optional, defaults to\n * master output)\n * @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n * to smooth amplitude readings\n * @example\n *
\n * function preload(){\n * sound1 = loadSound('assets/beat.mp3');\n * sound2 = loadSound('assets/drum.mp3');\n * }\n * function setup(){\n * cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n *\n * amplitude = new p5.Amplitude();\n * amplitude.setInput(sound2);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap to play', 20, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound1.isPlaying() && sound2.isPlaying()) {\n * sound1.stop();\n * sound2.stop();\n * } else {\n * sound1.play();\n * sound2.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.setInput = function (source, smoothing) {\n p5sound.meter.disconnect();\n\n if (smoothing) {\n this._workletNode.parameters.get('smoothing').value = smoothing;\n }\n\n // connect to the master out of p5s instance if no snd is provided\n if (source == null) {\n console.log(\n 'Amplitude input source is not ready! Connecting to master output instead'\n );\n p5sound.meter.connect(this._workletNode);\n }\n\n // if it is a p5.Signal\n else if (source instanceof p5.Signal) {\n source.output.connect(this._workletNode);\n }\n // connect to the sound if it is available\n else if (source) {\n source.connect(this._workletNode);\n this._workletNode.disconnect();\n this._workletNode.connect(this.output);\n }\n\n // otherwise, connect to the master out of p5s instance (default)\n else {\n p5sound.meter.connect(this._workletNode);\n }\n };\n\n p5.Amplitude.prototype.connect = function (unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(this.panner.connect(p5sound.input));\n }\n };\n\n p5.Amplitude.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Returns a single Amplitude reading at the moment it is called.\n * For continuous readings, run in the draw loop.\n *\n * @method getLevel\n * @for p5.Amplitude\n * @param {Number} [channel] Optionally return only channel 0 (left) or 1 (right)\n * @return {Number} Amplitude as a number between 0.0 and 1.0\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mouseClicked(toggleSound);\n * amplitude = new p5.Amplitude();\n * }\n *\n * function draw() {\n * background(220, 150);\n * textAlign(CENTER);\n * text('tap to play', width/2, 20);\n *\n * let level = amplitude.getLevel();\n * let size = map(level, 0, 1, 0, 200);\n * ellipse(width/2, height/2, size, size);\n * }\n *\n * function toggleSound(){\n * if (sound.isPlaying()) {\n * sound.stop();\n * } else {\n * sound.play();\n * }\n * }\n *
\n */\n p5.Amplitude.prototype.getLevel = function (channel) {\n if (typeof channel !== 'undefined') {\n if (this.normalize) {\n return this.stereoVolNorm[channel];\n } else {\n return this.stereoVol[channel];\n }\n } else if (this.normalize) {\n return this.volNorm;\n } else {\n return this.volume;\n }\n };\n\n /**\n * Determines whether the results of Amplitude.process() will be\n * Normalized. To normalize, Amplitude finds the difference the\n * loudest reading it has processed and the maximum amplitude of\n * 1.0. Amplitude adds this difference to all values to produce\n * results that will reliably map between 0.0 and 1.0. However,\n * if a louder moment occurs, the amount that Normalize adds to\n * all the values will change. Accepts an optional boolean parameter\n * (true or false). Normalizing is off by default.\n *\n * @method toggleNormalize\n * @for p5.Amplitude\n * @param {boolean} [boolean] set normalize to true (1) or false (0)\n */\n p5.Amplitude.prototype.toggleNormalize = function (bool) {\n if (typeof bool === 'boolean') {\n this.normalize = bool;\n } else {\n this.normalize = !this.normalize;\n }\n this._workletNode.port.postMessage({\n name: 'toggleNormalize',\n normalize: this.normalize,\n });\n };\n\n /**\n * Smooth Amplitude analysis by averaging with the last analysis\n * frame. Off by default.\n *\n * @method smooth\n * @for p5.Amplitude\n * @param {Number} set smoothing from 0.0 <= 1\n */\n p5.Amplitude.prototype.smooth = function (s) {\n if (s >= 0 && s < 1) {\n this._workletNode.port.postMessage({ name: 'smoothing', smoothing: s });\n } else {\n console.log('Error: smoothing must be between 0 and 1');\n }\n };\n\n p5.Amplitude.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n\n this._workletNode.disconnect();\n delete this._workletNode;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n *

FFT (Fast Fourier Transform) is an analysis algorithm that\n * isolates individual\n * \n * audio frequencies within a waveform.

\n *\n *

Once instantiated, a p5.FFT object can return an array based on\n * two types of analyses:
• FFT.waveform() computes\n * amplitude values along the time domain. The array indices correspond\n * to samples across a brief moment in time. Each value represents\n * amplitude of the waveform at that sample of time.
\n * • FFT.analyze() computes amplitude values along the\n * frequency domain. The array indices correspond to frequencies (i.e.\n * pitches), from the lowest to the highest that humans can hear. Each\n * value represents amplitude at that slice of the frequency spectrum.\n * Use with getEnergy() to measure amplitude at specific\n * frequencies, or within a range of frequencies.

\n *\n *

FFT analyzes a very short snapshot of sound called a sample\n * buffer. It returns an array of amplitude measurements, referred\n * to as bins. The array is 1024 bins long by default.\n * You can change the bin array length, but it must be a power of 2\n * between 16 and 1024 in order for the FFT algorithm to function\n * correctly. The actual size of the FFT buffer is twice the\n * number of bins, so given a standard sample rate, the buffer is\n * 2048/44100 seconds long.

\n *\n *\n * @class p5.FFT\n * @constructor\n * @param {Number} [smoothing] Smooth results of Freq Spectrum.\n * 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n * @param {Number} [bins] Length of resulting array.\n * Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @example\n *
\n * function preload(){\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mouseClicked(togglePlay);\n * fft = new p5.FFT();\n * sound.amp(0.2);\n * }\n *\n * function draw(){\n * background(220);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h )\n * }\n *\n * let waveform = fft.waveform();\n * noFill();\n * beginShape();\n * stroke(20);\n * for (let i = 0; i < waveform.length; i++){\n * let x = map(i, 0, waveform.length, 0, width);\n * let y = map( waveform[i], -1, 1, 0, height);\n * vertex(x,y);\n * }\n * endShape();\n *\n * text('tap to play', 20, 20);\n * }\n *\n * function togglePlay() {\n * if (sound.isPlaying()) {\n * sound.pause();\n * } else {\n * sound.loop();\n * }\n * }\n *
\n */\n p5.FFT = function (smoothing, bins) {\n this.input = this.analyser = p5sound.audiocontext.createAnalyser();\n\n Object.defineProperties(this, {\n bins: {\n get: function () {\n return this.analyser.fftSize / 2;\n },\n set: function (b) {\n this.analyser.fftSize = b * 2;\n },\n configurable: true,\n enumerable: true,\n },\n smoothing: {\n get: function () {\n return this.analyser.smoothingTimeConstant;\n },\n set: function (s) {\n this.analyser.smoothingTimeConstant = s;\n },\n configurable: true,\n enumerable: true,\n },\n });\n\n // set default smoothing and bins\n this.smooth(smoothing);\n this.bins = bins || 1024;\n\n // default connections to p5sound fftMeter\n p5sound.fftMeter.connect(this.analyser);\n\n this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n\n // predefined frequency ranges, these will be tweakable\n this.bass = [20, 140];\n this.lowMid = [140, 400];\n this.mid = [400, 2600];\n this.highMid = [2600, 5200];\n this.treble = [5200, 14000];\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Set the input source for the FFT analysis. If no source is\n * provided, FFT will analyze all sound in the sketch.\n *\n * @method setInput\n * @for p5.FFT\n * @param {Object} [source] p5.sound object (or web audio API source node)\n */\n p5.FFT.prototype.setInput = function (source) {\n if (!source) {\n p5sound.fftMeter.connect(this.analyser);\n } else {\n if (source.output) {\n source.output.connect(this.analyser);\n } else if (source.connect) {\n source.connect(this.analyser);\n }\n p5sound.fftMeter.disconnect();\n }\n };\n\n /**\n * Returns an array of amplitude values (between -1.0 and +1.0) that represent\n * a snapshot of amplitude readings in a single buffer. Length will be\n * equal to bins (defaults to 1024). Can be used to draw the waveform\n * of a sound.\n *\n * @method waveform\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {String} [precision] If any value is provided, will return results\n * in a Float32 Array which is more precise\n * than a regular array.\n * @return {Array} Array Array of amplitude values (-1 to 1)\n * over time. Array length = bins.\n *\n */\n p5.FFT.prototype.waveform = function () {\n var bins, mode;\n var normalArray = new Array();\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n bins = arguments[i];\n this.analyser.fftSize = bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n // getFloatFrequencyData doesnt work in Safari as of 5/2015\n if (mode && !p5.prototype._isSafari()) {\n timeToFloat(this, this.timeDomain);\n this.analyser.getFloatTimeDomainData(this.timeDomain);\n return this.timeDomain;\n } else {\n timeToInt(this, this.timeDomain);\n this.analyser.getByteTimeDomainData(this.timeDomain);\n for (var j = 0; j < this.timeDomain.length; j++) {\n var scaled = p5.prototype.map(this.timeDomain[j], 0, 255, -1, 1);\n normalArray.push(scaled);\n }\n return normalArray;\n }\n };\n\n /**\n * Returns an array of amplitude values (between 0 and 255)\n * across the frequency spectrum. Length is equal to FFT bins\n * (1024 by default). The array indices correspond to frequencies\n * (i.e. pitches), from the lowest to the highest that humans can\n * hear. Each value represents amplitude at that slice of the\n * frequency spectrum. Must be called prior to using\n * getEnergy().\n *\n * @method analyze\n * @for p5.FFT\n * @param {Number} [bins] Must be a power of two between\n * 16 and 1024. Defaults to 1024.\n * @param {Number} [scale] If \"dB,\" returns decibel\n * float measurements between\n * -140 and 0 (max).\n * Otherwise returns integers from 0-255.\n * @return {Array} spectrum Array of energy (amplitude/volume)\n * values across the frequency spectrum.\n * Lowest energy (silence) = 0, highest\n * possible is 255.\n * @example\n *
\n * let osc, fft;\n *\n * function setup(){\n * let cnv = createCanvas(100,100);\n * cnv.mousePressed(startSound);\n * osc = new p5.Oscillator();\n * osc.amp(0);\n * fft = new p5.FFT();\n * }\n *\n * function draw(){\n * background(220);\n *\n * let freq = map(mouseX, 0, windowWidth, 20, 10000);\n * freq = constrain(freq, 1, 20000);\n * osc.freq(freq);\n *\n * let spectrum = fft.analyze();\n * noStroke();\n * fill(255, 0, 255);\n * for (let i = 0; i< spectrum.length; i++){\n * let x = map(i, 0, spectrum.length, 0, width);\n * let h = -height + map(spectrum[i], 0, 255, height, 0);\n * rect(x, height, width / spectrum.length, h );\n * }\n *\n * stroke(255);\n * if (!osc.started) {\n * text('tap here and drag to change frequency', 10, 20, width - 20);\n * } else {\n * text(round(freq)+'Hz', 10, 20);\n * }\n * }\n *\n * function startSound() {\n * osc.start();\n * osc.amp(0.5, 0.2);\n * }\n *\n * function mouseReleased() {\n * osc.amp(0, 0.2);\n * }\n *
\n *\n *\n */\n p5.FFT.prototype.analyze = function () {\n var mode;\n\n for (var i = 0; i < arguments.length; i++) {\n if (typeof arguments[i] === 'number') {\n this.bins = arguments[i];\n this.analyser.fftSize = this.bins * 2;\n }\n if (typeof arguments[i] === 'string') {\n mode = arguments[i];\n }\n }\n\n if (mode && mode.toLowerCase() === 'db') {\n freqToFloat(this);\n this.analyser.getFloatFrequencyData(this.freqDomain);\n return this.freqDomain;\n } else {\n freqToInt(this, this.freqDomain);\n this.analyser.getByteFrequencyData(this.freqDomain);\n var normalArray = Array.apply([], this.freqDomain);\n\n return normalArray;\n }\n };\n\n /**\n * Returns the amount of energy (volume) at a specific\n * \n * frequency, or the average amount of energy between two\n * frequencies. Accepts Number(s) corresponding\n * to frequency (in Hz), or a String corresponding to predefined\n * frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n * Returns a range between 0 (no energy/volume at that frequency) and\n * 255 (maximum energy).\n * NOTE: analyze() must be called prior to getEnergy(). Analyze()\n * tells the FFT to analyze frequency data, and getEnergy() uses\n * the results determine the value at a specific frequency or\n * range of frequencies.

\n *\n * @method getEnergy\n * @for p5.FFT\n * @param {Number|String} frequency1 Will return a value representing\n * energy at this frequency. Alternately,\n * the strings \"bass\", \"lowMid\" \"mid\",\n * \"highMid\", and \"treble\" will return\n * predefined frequency ranges.\n * @param {Number} [frequency2] If a second frequency is given,\n * will return average amount of\n * energy that exists between the\n * two frequencies.\n * @return {Number} Energy Energy (volume/amplitude) from\n * 0 and 255.\n *\n */\n p5.FFT.prototype.getEnergy = function (frequency1, frequency2) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n\n if (frequency1 === 'bass') {\n frequency1 = this.bass[0];\n frequency2 = this.bass[1];\n } else if (frequency1 === 'lowMid') {\n frequency1 = this.lowMid[0];\n frequency2 = this.lowMid[1];\n } else if (frequency1 === 'mid') {\n frequency1 = this.mid[0];\n frequency2 = this.mid[1];\n } else if (frequency1 === 'highMid') {\n frequency1 = this.highMid[0];\n frequency2 = this.highMid[1];\n } else if (frequency1 === 'treble') {\n frequency1 = this.treble[0];\n frequency2 = this.treble[1];\n }\n\n if (typeof frequency1 !== 'number') {\n throw 'invalid input for getEnergy()';\n } else if (!frequency2) {\n // if only one parameter:\n var index = Math.round((frequency1 / nyquist) * this.freqDomain.length);\n return this.freqDomain[index];\n } else if (frequency1 && frequency2) {\n // if two parameters:\n // if second is higher than first\n if (frequency1 > frequency2) {\n var swap = frequency2;\n frequency2 = frequency1;\n frequency1 = swap;\n }\n var lowIndex = Math.round(\n (frequency1 / nyquist) * this.freqDomain.length\n );\n var highIndex = Math.round(\n (frequency2 / nyquist) * this.freqDomain.length\n );\n\n var total = 0;\n var numFrequencies = 0;\n // add up all of the values for the frequencies\n for (var i = lowIndex; i <= highIndex; i++) {\n total += this.freqDomain[i];\n numFrequencies += 1;\n }\n // divide by total number of frequencies\n var toReturn = total / numFrequencies;\n return toReturn;\n } else {\n throw 'invalid input for getEnergy()';\n }\n };\n\n // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n p5.FFT.prototype.getFreq = function (freq1, freq2) {\n console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n var x = this.getEnergy(freq1, freq2);\n return x;\n };\n\n /**\n * Returns the\n * \n * spectral centroid of the input signal.\n * NOTE: analyze() must be called prior to getCentroid(). Analyze()\n * tells the FFT to analyze frequency data, and getCentroid() uses\n * the results determine the spectral centroid.

\n *\n * @method getCentroid\n * @for p5.FFT\n * @return {Number} Spectral Centroid Frequency of the spectral centroid in Hz.\n *\n *\n * @example\n *
\n * function setup(){\n * cnv = createCanvas(100,100);\n * cnv.mousePressed(userStartAudio);\n * sound = new p5.AudioIn();\n * sound.start();\n * fft = new p5.FFT();\n * sound.connect(fft);\n *}\n *\n *function draw() {\n * if (getAudioContext().state !== 'running') {\n * background(220);\n * text('tap here and enable mic to begin', 10, 20, width - 20);\n * return;\n * }\n * let centroidplot = 0.0;\n * let spectralCentroid = 0;\n *\n * background(0);\n * stroke(0,255,0);\n * let spectrum = fft.analyze();\n * fill(0,255,0); // spectrum is green\n *\n * //draw the spectrum\n * for (let i = 0; i < spectrum.length; i++){\n * let x = map(log(i), 0, log(spectrum.length), 0, width);\n * let h = map(spectrum[i], 0, 255, 0, height);\n * let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n * rect(x, height, rectangle_width, -h )\n * }\n * let nyquist = 22050;\n *\n * // get the centroid\n * spectralCentroid = fft.getCentroid();\n *\n * // the mean_freq_index calculation is for the display.\n * let mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n *\n * centroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n *\n * stroke(255,0,0); // the line showing where the centroid is will be red\n *\n * rect(centroidplot, 0, width / spectrum.length, height)\n * noStroke();\n * fill(255,255,255); // text is white\n * text('centroid: ', 10, 20);\n * text(round(spectralCentroid)+' Hz', 10, 40);\n *}\n *
\n */\n p5.FFT.prototype.getCentroid = function () {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var cumulative_sum = 0;\n var centroid_normalization = 0;\n\n for (var i = 0; i < this.freqDomain.length; i++) {\n cumulative_sum += i * this.freqDomain[i];\n centroid_normalization += this.freqDomain[i];\n }\n\n var mean_freq_index = 0;\n\n if (centroid_normalization !== 0) {\n mean_freq_index = cumulative_sum / centroid_normalization;\n }\n\n var spec_centroid_freq =\n mean_freq_index * (nyquist / this.freqDomain.length);\n return spec_centroid_freq;\n };\n\n /**\n * Smooth FFT analysis by averaging with the last analysis frame.\n *\n * @method smooth\n * @param {Number} smoothing 0.0 < smoothing < 1.0.\n * Defaults to 0.8.\n */\n p5.FFT.prototype.smooth = function (s) {\n if (typeof s !== 'undefined') {\n this.smoothing = s;\n }\n return this.smoothing;\n };\n\n p5.FFT.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.analyser) {\n this.analyser.disconnect();\n delete this.analyser;\n }\n };\n\n /**\n * Returns an array of average amplitude values for a given number\n * of frequency bands split equally. N defaults to 16.\n * NOTE: analyze() must be called prior to linAverages(). Analyze()\n * tells the FFT to analyze frequency data, and linAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method linAverages\n * @for p5.FFT\n * @param {Number} N Number of returned frequency groups\n * @return {Array} linearAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.linAverages = function (_N) {\n var N = _N || 16; // This prevents undefined, null or 0 values of N\n\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n var spectrumStep = Math.floor(spectrumLength / N);\n\n var linearAverages = new Array(N);\n // Keep a second index for the current average group and place the values accordingly\n // with only one loop in the spectrum data\n var groupIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n linearAverages[groupIndex] =\n linearAverages[groupIndex] !== undefined\n ? (linearAverages[groupIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n\n // Increase the group index when the last element of the group is processed\n if (specIndex % spectrumStep === spectrumStep - 1) {\n groupIndex++;\n }\n }\n\n return linearAverages;\n };\n\n /**\n * Returns an array of average amplitude values of the spectrum, for a given\n * set of \n * Octave Bands\n * NOTE: analyze() must be called prior to logAverages(). Analyze()\n * tells the FFT to analyze frequency data, and logAverages() uses\n * the results to group them into a smaller set of averages.

\n *\n * @method logAverages\n * @for p5.FFT\n * @param {Array} octaveBands Array of Octave Bands objects for grouping\n * @return {Array} logAverages Array of average amplitude values for each group\n */\n p5.FFT.prototype.logAverages = function (octaveBands) {\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n var spectrum = this.freqDomain;\n var spectrumLength = spectrum.length;\n\n var logAverages = new Array(octaveBands.length);\n // Keep a second index for the current average group and place the values accordingly\n // With only one loop in the spectrum data\n var octaveIndex = 0;\n\n for (var specIndex = 0; specIndex < spectrumLength; specIndex++) {\n var specIndexFrequency = Math.round(\n (specIndex * nyquist) / this.freqDomain.length\n );\n\n // Increase the group index if the current frequency exceeds the limits of the band\n if (specIndexFrequency > octaveBands[octaveIndex].hi) {\n octaveIndex++;\n }\n\n logAverages[octaveIndex] =\n logAverages[octaveIndex] !== undefined\n ? (logAverages[octaveIndex] + spectrum[specIndex]) / 2\n : spectrum[specIndex];\n }\n\n return logAverages;\n };\n\n /**\n * Calculates and Returns the 1/N\n * Octave Bands\n * N defaults to 3 and minimum central frequency to 15.625Hz.\n * (1/3 Octave Bands ~= 31 Frequency Bands)\n * Setting fCtr0 to a central value of a higher octave will ignore the lower bands\n * and produce less frequency groups.\n *\n * @method getOctaveBands\n * @for p5.FFT\n * @param {Number} N Specifies the 1/N type of generated octave bands\n * @param {Number} fCtr0 Minimum central frequency for the lowest band\n * @return {Array} octaveBands Array of octave band objects with their bounds\n */\n p5.FFT.prototype.getOctaveBands = function (_N, _fCtr0) {\n var N = _N || 3; // Default to 1/3 Octave Bands\n var fCtr0 = _fCtr0 || 15.625; // Minimum central frequency, defaults to 15.625Hz\n\n var octaveBands = [];\n var lastFrequencyBand = {\n lo: fCtr0 / Math.pow(2, 1 / (2 * N)),\n ctr: fCtr0,\n hi: fCtr0 * Math.pow(2, 1 / (2 * N)),\n };\n octaveBands.push(lastFrequencyBand);\n\n var nyquist = p5sound.audiocontext.sampleRate / 2;\n while (lastFrequencyBand.hi < nyquist) {\n var newFrequencyBand = {};\n newFrequencyBand.lo = lastFrequencyBand.hi;\n newFrequencyBand.ctr = lastFrequencyBand.ctr * Math.pow(2, 1 / N);\n newFrequencyBand.hi = newFrequencyBand.ctr * Math.pow(2, 1 / (2 * N));\n\n octaveBands.push(newFrequencyBand);\n lastFrequencyBand = newFrequencyBand;\n }\n\n return octaveBands;\n };\n\n // helper methods to convert type from float (dB) to int (0-255)\n function freqToFloat(fft) {\n if (fft.freqDomain instanceof Float32Array === false) {\n fft.freqDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n }\n function freqToInt(fft) {\n if (fft.freqDomain instanceof Uint8Array === false) {\n fft.freqDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n }\n function timeToFloat(fft) {\n if (fft.timeDomain instanceof Float32Array === false) {\n fft.timeDomain = new Float32Array(fft.analyser.frequencyBinCount);\n }\n }\n function timeToInt(fft) {\n if (fft.timeDomain instanceof Uint8Array === false) {\n fft.timeDomain = new Uint8Array(fft.analyser.frequencyBinCount);\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n // Signal is built with the Tone.js signal by Yotam Mann\n // https://github.com/TONEnoTONE/Tone.js/\n var Signal = require('Tone/signal/Signal');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n\n /**\n *

p5.Signal is a constant audio-rate signal used by p5.Oscillator\n * and p5.Envelope for modulation math.

\n *\n *

This is necessary because Web Audio is processed on a separate clock.\n * For example, the p5 draw loop runs about 60 times per second. But\n * the audio clock must process samples 44100 times per second. If we\n * want to add a value to each of those samples, we can't do it in the\n * draw loop, but we can do it by adding a constant-rate audio signal.This class mostly functions behind the scenes in p5.sound, and returns\n * a Tone.Signal from the Tone.js library by Yotam Mann.\n * If you want to work directly with audio signals for modular\n * synthesis, check out\n * tone.js.

\n *\n * @class p5.Signal\n * @constructor\n * @return {Tone.Signal} A Signal object from the Tone.js library\n * @example\n *
\n * let carrier, modulator;\n * let hasStarted = false;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * carrier = new p5.Oscillator('sine');\n * carrier.amp(1); // set amplitude\n * carrier.freq(220); // set frequency\n *\n * modulator = new p5.Oscillator('sawtooth');\n * modulator.disconnect();\n * modulator.start();\n * modulator.amp(1);\n * modulator.freq(4);\n *\n * // Modulator's default amplitude range is -1 to 1.\n * // Multiply it by -200, so the range is -200 to 200\n * // then add 220 so the range is 20 to 420\n * carrier.freq( modulator.mult(-400).add(220) );\n * }\n *\n * function canvasPressed() {\n * userStartAudio();\n * carrier.amp(1.0);\n * if(!hasStarted){\n * carrier.start();\n * hasStarted = true;\n * }\n * }\n *\n * function mouseReleased() {\n * carrier.amp(0);\n * }\n *
\n */\n p5.Signal = function (value) {\n var s = new Signal(value);\n // p5sound.soundArray.push(s);\n return s; // TODO: is this really a constructor?\n };\n\n /**\n * Fade to value, for smooth transitions\n *\n * @method fade\n * @for p5.Signal\n * @param {Number} value Value to set this signal\n * @param {Number} [secondsFromNow] Length of fade, in seconds from now\n */\n Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n Mult.prototype.fade = Signal.prototype.fade;\n Add.prototype.fade = Signal.prototype.fade;\n Scale.prototype.fade = Signal.prototype.fade;\n\n /**\n * Connect a p5.sound object or Web Audio node to this\n * p5.Signal so that its amplitude values can be scaled.\n *\n * @method setInput\n * @for p5.Signal\n * @param {Object} input\n */\n Signal.prototype.setInput = function (_input) {\n _input.connect(this);\n };\n Mult.prototype.setInput = Signal.prototype.setInput;\n Add.prototype.setInput = Signal.prototype.setInput;\n Scale.prototype.setInput = Signal.prototype.setInput;\n\n // signals can add / mult / scale themselves\n\n /**\n * Add a constant value to this audio signal,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalAdd.\n *\n * @method add\n * @for p5.Signal\n * @param {Number} number\n * @return {p5.Signal} object\n */\n Signal.prototype.add = function (num) {\n var add = new Add(num);\n // add.setInput(this);\n this.connect(add);\n return add;\n };\n Mult.prototype.add = Signal.prototype.add;\n Add.prototype.add = Signal.prototype.add;\n Scale.prototype.add = Signal.prototype.add;\n\n /**\n * Multiply this signal by a constant value,\n * and return the resulting audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalMult.\n *\n * @method mult\n * @for p5.Signal\n * @param {Number} number to multiply\n * @return {p5.Signal} object\n */\n Signal.prototype.mult = function (num) {\n var mult = new Mult(num);\n // mult.setInput(this);\n this.connect(mult);\n return mult;\n };\n Mult.prototype.mult = Signal.prototype.mult;\n Add.prototype.mult = Signal.prototype.mult;\n Scale.prototype.mult = Signal.prototype.mult;\n\n /**\n * Scale this signal value to a given range,\n * and return the result as an audio signal. Does\n * not change the value of the original signal,\n * instead it returns a new p5.SignalScale.\n *\n * @method scale\n * @for p5.Signal\n * @param {Number} number to multiply\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Signal} object\n */\n Signal.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var mapOutMin, mapOutMax;\n if (arguments.length === 4) {\n mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n } else {\n mapOutMin = arguments[0];\n mapOutMax = arguments[1];\n }\n var scale = new Scale(mapOutMin, mapOutMax);\n this.connect(scale);\n return scale;\n };\n Mult.prototype.scale = Signal.prototype.scale;\n Add.prototype.scale = Signal.prototype.scale;\n Scale.prototype.scale = Signal.prototype.scale;\n});\n","define([\"Tone/core/Tone\", \"Tone/type/TimeBase\"], function (Tone) {\n\n\t/**\n\t * @class Tone.Frequency is a primitive type for encoding Frequency values. \n\t * Eventually all time values are evaluated to hertz\n\t * using the `eval` method. \n\t * @constructor\n\t * @extends {Tone.TimeBase}\n\t * @param {String|Number} val The time value.\n\t * @param {String=} units The units of the value.\n\t * @example\n\t * Tone.Frequency(\"C3\") // 261\n\t * Tone.Frequency(38, \"midi\") //\n\t * Tone.Frequency(\"C3\").transpose(4);\n\t */\n\tTone.Frequency = function(val, units){\n\t\tif (this instanceof Tone.Frequency){\n\t\t\t\n\t\t\tTone.TimeBase.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.Frequency(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.Frequency, Tone.TimeBase);\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tAUGMENT BASE EXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions);\n\n\t/*\n\t * midi type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.midi = {\n\t\tregexp : /^(\\d+(?:\\.\\d+)?midi)/,\n\t\tmethod : function(value){\n\t\t\treturn this.midiToFrequency(value);\n\t\t}\t\n\t};\n\n\t/*\n\t * note type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.note = {\n\t\tregexp : /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n\t\tmethod : function(pitch, octave){\n\t\t\tvar index = noteToScaleIndex[pitch.toLowerCase()];\n\t\t\tvar noteNumber = index + (parseInt(octave) + 1) * 12;\n\t\t\treturn this.midiToFrequency(noteNumber);\n\t\t}\t\n\t};\n\n\t/*\n\t * BeatsBarsSixteenths type primary expression\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Frequency.prototype._primaryExpressions.tr = {\n\t\t\tregexp : /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n\t\t\tmethod : function(m, q, s){\n\t\t\tvar total = 1;\n\t\t\tif (m && m !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(this._timeSignature() * parseFloat(m));\n\t\t\t}\n\t\t\tif (q && q !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(q));\n\t\t\t}\n\t\t\tif (s && s !== \"0\"){\n\t\t\t\ttotal *= this._beatsToUnits(parseFloat(s) / 4);\n\t\t\t}\n\t\t\treturn total;\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tEXPRESSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Transposes the frequency by the given number of semitones.\n\t * @param {Interval} interval\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").transpose(3); //\"C5\"\n\t */\n\tTone.Frequency.prototype.transpose = function(interval){\n\t\tthis._expr = function(expr, interval){\n\t\t\tvar val = expr();\n\t\t\treturn val * this.intervalToFrequencyRatio(interval);\n\t\t}.bind(this, this._expr, interval);\n\t\treturn this;\n\t};\n\n\t/**\n\t * Takes an array of semitone intervals and returns\n\t * an array of frequencies transposed by those intervals.\n\t * @param {Array} intervals\n\t * @return {Tone.Frequency} this\n\t * @example\n\t * Tone.Frequency(\"A4\").harmonize([0, 3, 7]); //[\"A4\", \"C5\", \"E5\"]\n\t */\n\tTone.Frequency.prototype.harmonize = function(intervals){\n\t\tthis._expr = function(expr, intervals){\n\t\t\tvar val = expr();\n\t\t\tvar ret = [];\n\t\t\tfor (var i = 0; i < intervals.length; i++){\n\t\t\t\tret[i] = val * this.intervalToFrequencyRatio(intervals[i]);\n\t\t\t}\n\t\t\treturn ret;\n\t\t}.bind(this, this._expr, intervals);\n\t\treturn this;\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Return the value of the frequency as a MIDI note\n\t * @return {MIDI}\n\t * @example\n\t * Tone.Frequency(\"C4\").toMidi(); //60\n\t */\n\tTone.Frequency.prototype.toMidi = function(){\n\t\treturn this.frequencyToMidi(this.valueOf());\n\t};\n\n\t/**\n\t * Return the value of the frequency in Scientific Pitch Notation\n\t * @return {Note}\n\t * @example\n\t * Tone.Frequency(69, \"midi\").toNote(); //\"A4\"\n\t */\n\tTone.Frequency.prototype.toNote = function(){\n\t\tvar freq = this.valueOf();\n\t\tvar log = Math.log(freq / Tone.Frequency.A4) / Math.LN2;\n\t\tvar noteNumber = Math.round(12 * log) + 57;\n\t\tvar octave = Math.floor(noteNumber/12);\n\t\tif(octave < 0){\n\t\t\tnoteNumber += -12 * octave;\n\t\t}\n\t\tvar noteName = scaleIndexToNote[noteNumber % 12];\n\t\treturn noteName + octave.toString();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.Frequency.prototype.toSeconds = function(){\n\t\treturn 1 / this.valueOf();\n\t};\n\n\t/**\n\t * Return the value in Hertz\n\t * @return {Frequency}\n\t */\n\tTone.Frequency.prototype.toFrequency = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the duration of one cycle in ticks\n\t * @return {Ticks}\n\t */\n\tTone.Frequency.prototype.toTicks = function(){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = this.valueOf() / quarterTime;\n\t\treturn Math.floor(quarters * Tone.Transport.PPQ);\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tUNIT CONVERSIONS HELPERS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Returns the value of a frequency in the current units\n\t * @param {Frequency} freq\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._frequencyToUnits = function(freq){\n\t\treturn freq;\n\t};\n\n\t/**\n\t * Returns the value of a tick in the current time units\n\t * @param {Ticks} ticks\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._ticksToUnits = function(ticks){\n\t\treturn 1 / ((ticks * 60) / (Tone.Transport.bpm.value * Tone.Transport.PPQ));\n\t};\n\n\t/**\n\t * Return the value of the beats in the current units\n\t * @param {Number} beats\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._beatsToUnits = function(beats){\n\t\treturn 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats);\n\t};\n\n\t/**\n\t * Returns the value of a second in the current units\n\t * @param {Seconds} seconds\n\t * @return {Number}\n\t * @private\n\t */\n\tTone.Frequency.prototype._secondsToUnits = function(seconds){\n\t\treturn 1 / seconds;\n\t};\n\n\t/**\n\t * The default units if none are given.\n\t * @private\n\t */\n\tTone.Frequency.prototype._defaultUnits = \"hz\";\n\n\t///////////////////////////////////////////////////////////////////////////\n\t//\tFREQUENCY CONVERSIONS\n\t///////////////////////////////////////////////////////////////////////////\n\n\t/**\n\t * Note to scale index\n\t * @type {Object}\n\t */\n\tvar noteToScaleIndex = {\n\t\t\"cbb\" : -2, \"cb\" : -1, \"c\" : 0, \"c#\" : 1, \"cx\" : 2, \n\t\t\"dbb\" : 0, \"db\" : 1, \"d\" : 2, \"d#\" : 3, \"dx\" : 4,\n\t\t\"ebb\" : 2, \"eb\" : 3, \"e\" : 4, \"e#\" : 5, \"ex\" : 6, \n\t\t\"fbb\" : 3, \"fb\" : 4, \"f\" : 5, \"f#\" : 6, \"fx\" : 7,\n\t\t\"gbb\" : 5, \"gb\" : 6, \"g\" : 7, \"g#\" : 8, \"gx\" : 9,\n\t\t\"abb\" : 7, \"ab\" : 8, \"a\" : 9, \"a#\" : 10, \"ax\" : 11,\n\t\t\"bbb\" : 9, \"bb\" : 10, \"b\" : 11, \"b#\" : 12, \"bx\" : 13,\n\t};\n\n\t/**\n\t * scale index to note (sharps)\n\t * @type {Array}\n\t */\n\tvar scaleIndexToNote = [\"C\", \"C#\", \"D\", \"D#\", \"E\", \"F\", \"F#\", \"G\", \"G#\", \"A\", \"A#\", \"B\"];\n\n\t/**\n\t * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch)\n\t * A4's values in Hertz. \n\t * @type {Frequency}\n\t * @static\n\t */\n\tTone.Frequency.A4 = 440;\n\n\t/**\n\t * Convert a MIDI note to frequency value. \n\t * @param {MIDI} midi The midi number to convert.\n\t * @return {Frequency} the corresponding frequency value\n\t * @example\n\t * tone.midiToFrequency(69); // returns 440\n\t */\n\tTone.Frequency.prototype.midiToFrequency = function(midi){\n\t\treturn Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12);\n\t};\n\n\t/**\n\t * Convert a frequency value to a MIDI note.\n\t * @param {Frequency} frequency The value to frequency value to convert.\n\t * @returns {MIDI}\n\t * @example\n\t * tone.midiToFrequency(440); // returns 69\n\t */\n\tTone.Frequency.prototype.frequencyToMidi = function(frequency){\n\t\treturn 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2;\n\t};\n\n\treturn Tone.Frequency;\n});","define([\"Tone/core/Tone\", \"Tone/type/Time\"], function (Tone) {\n\n\t/**\n\t * @class Tone.TransportTime is a the time along the Transport's\n\t * timeline. It is similar to Tone.Time, but instead of evaluating\n\t * against the AudioContext's clock, it is evaluated against\n\t * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n\t * @constructor\n\t * @param {Time} val The time value as a number or string\n\t * @param {String=} units Unit values\n\t * @extends {Tone.Time}\n\t */\n\tTone.TransportTime = function(val, units){\n\t\tif (this instanceof Tone.TransportTime){\n\t\t\t\n\t\t\tTone.Time.call(this, val, units);\n\n\t\t} else {\n\t\t\treturn new Tone.TransportTime(val, units);\n\t\t}\n\t};\n\n\tTone.extend(Tone.TransportTime, Tone.Time);\n\n\t//clone the expressions so that \n\t//we can add more without modifying the original\n\tTone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions);\n\n\t/**\n\t * Adds an additional unary expression\n\t * which quantizes values to the next subdivision\n\t * @type {Object}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._unaryExpressions.quantize = {\n\t\tregexp : /^@/,\n\t\tmethod : function(rh){\n\t\t\tvar subdivision = this._secondsToTicks(rh());\n\t\t\tvar multiple = Math.ceil(Tone.Transport.ticks / subdivision);\n\t\t\treturn this._ticksToUnits(multiple * subdivision);\n\t\t}\n\t};\n\n\t/**\n\t * Convert seconds into ticks\n\t * @param {Seconds} seconds\n\t * @return {Ticks}\n\t * @private\n\t */\n\tTone.TransportTime.prototype._secondsToTicks = function(seconds){\n\t\tvar quarterTime = this._beatsToUnits(1);\n\t\tvar quarters = seconds / quarterTime;\n\t\treturn Math.round(quarters * Tone.Transport.PPQ);\n\t};\n\n\t/**\n\t * Evaluate the time expression. Returns values in ticks\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.valueOf = function(){\n\t\tvar val = this._secondsToTicks(this._expr());\n\t\treturn val + (this._plusNow ? Tone.Transport.ticks : 0);\n\t};\n\n\t/**\n\t * Return the time in ticks.\n\t * @return {Ticks}\n\t */\n\tTone.TransportTime.prototype.toTicks = function(){\n\t\treturn this.valueOf();\n\t};\n\n\t/**\n\t * Return the time in seconds.\n\t * @return {Seconds}\n\t */\n\tTone.TransportTime.prototype.toSeconds = function(){\n\t\tvar val = this._expr();\n\t\treturn val + (this._plusNow ? Tone.Transport.seconds : 0);\n\t};\n\n\t/**\n\t * Return the time as a frequency value\n\t * @return {Frequency} \n\t */\n\tTone.TransportTime.prototype.toFrequency = function(){\n\t\treturn 1/this.toSeconds();\n\t};\n\n\treturn Tone.TransportTime;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Add = require('Tone/signal/Add');\n var Mult = require('Tone/signal/Multiply');\n var Scale = require('Tone/signal/Scale');\n var TimelineSignal = require('Tone/signal/TimelineSignal');\n\n /**\n *

Envelopes are pre-defined amplitude distribution over time.\n * Typically, envelopes are used to control the output volume\n * of an object, a series of fades referred to as Attack, Decay,\n * Sustain and Release (\n * ADSR\n * ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\n * control an Oscillator's frequency like this: osc.freq(env).

\n *

Use setRange to change the attack/release level.\n * Use setADSR to change attackTime, decayTime, sustainPercent and releaseTime.

\n *

Use the play method to play the entire envelope,\n * the ramp method for a pingable trigger,\n * or triggerAttack/\n * triggerRelease to trigger noteOn/noteOff.

\n *\n * @class p5.Envelope\n * @constructor\n * @example\n *
\n * let t1 = 0.1; // attack time in seconds\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n *\n * let env;\n * let triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * text('tap to play', 20, 20);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope(t1, l1, t2, l2);\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function playSound() {\n * // starting the oscillator ensures that audio is enabled.\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n */\n p5.Envelope = function (t1, l1, t2, l2, t3, l3) {\n /**\n * Time until envelope reaches attackLevel\n * @property attackTime\n */\n this.aTime = t1 || 0.1;\n /**\n * Level once attack is complete.\n * @property attackLevel\n */\n this.aLevel = l1 || 1;\n /**\n * Time until envelope reaches decayLevel.\n * @property decayTime\n */\n this.dTime = t2 || 0.5;\n /**\n * Level after decay. The envelope will sustain here until it is released.\n * @property decayLevel\n */\n this.dLevel = l2 || 0;\n /**\n * Duration of the release portion of the envelope.\n * @property releaseTime\n */\n this.rTime = t3 || 0;\n /**\n * Level at the end of the release.\n * @property releaseLevel\n */\n this.rLevel = l3 || 0;\n\n this._rampHighPercentage = 0.98;\n\n this._rampLowPercentage = 0.02;\n\n this.output = p5sound.audiocontext.createGain();\n\n this.control = new TimelineSignal();\n\n this._init(); // this makes sure the envelope starts at zero\n\n this.control.connect(this.output); // connect to the output\n\n this.connection = null; // store connection\n\n //array of math operation signal chaining\n this.mathOps = [this.control];\n\n //whether envelope should be linear or exponential curve\n this.isExponential = false;\n\n // oscillator or buffer source to clear on env complete\n // to save resources if/when it is retriggered\n this.sourceToClear = null;\n\n // set to true if attack is set, then false on release\n this.wasTriggered = false;\n\n // add to the soundArray so we can dispose of the env later\n p5sound.soundArray.push(this);\n };\n\n // this init function just smooths the starting value to zero and gives a start point for the timeline\n // - it was necessary to remove glitches at the beginning.\n p5.Envelope.prototype._init = function () {\n var now = p5sound.audiocontext.currentTime;\n var t = now;\n this.control.setTargetAtTime(0.00001, t, 0.001);\n //also, compute the correct time constants\n this._setRampAD(this.aTime, this.dTime);\n };\n\n /**\n * Reset the envelope with a series of time/value pairs.\n *\n * @method set\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds) before level\n * reaches attackLevel\n * @param {Number} attackLevel Typically an amplitude between\n * 0.0 and 1.0\n * @param {Number} decayTime Time\n * @param {Number} decayLevel Amplitude (In a standard ADSR envelope,\n * decayLevel = sustainLevel)\n * @param {Number} releaseTime Release Time (in seconds)\n * @param {Number} releaseLevel Amplitude\n * @example\n *
\n * let attackTime;\n * let l1 = 0.7; // attack level 0.0 to 1.0\n * let t2 = 0.3; // decay time in seconds\n * let l2 = 0.1; // decay level 0.0 to 1.0\n * let l3 = 0.2; // release time in seconds\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n *\n * attackTime = map(mouseX, 0, width, 0.0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 20);\n * }\n *\n * // mouseClick triggers envelope if over canvas\n * function playSound() {\n * env.set(attackTime, l1, t2, l2, l3);\n *\n * triOsc.start();\n * env.play(triOsc);\n * }\n *
\n *\n */\n p5.Envelope.prototype.set = function (t1, l1, t2, l2, t3, l3) {\n this.aTime = t1;\n this.aLevel = l1;\n this.dTime = t2 || 0;\n this.dLevel = l2 || 0;\n this.rTime = t3 || 0;\n this.rLevel = l3 || 0;\n\n // set time constants for ramp\n this._setRampAD(t1, t2);\n };\n\n /**\n * Set values like a traditional\n * \n * ADSR envelope\n * .\n *\n * @method setADSR\n * @for p5.Envelope\n * @param {Number} attackTime Time (in seconds before envelope\n * reaches Attack Level\n * @param {Number} [decayTime] Time (in seconds) before envelope\n * reaches Decay/Sustain Level\n * @param {Number} [susRatio] Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n * where 1.0 = attackLevel, 0.0 = releaseLevel.\n * The susRatio determines the decayLevel and the level at which the\n * sustain portion of the envelope will sustain.\n * For example, if attackLevel is 0.4, releaseLevel is 0,\n * and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n * increased to 1.0 (using setRange),\n * then decayLevel would increase proportionally, to become 0.5.\n * @param {Number} [releaseTime] Time in seconds from now (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setADSR = function (aTime, dTime, sPercent, rTime) {\n this.aTime = aTime;\n this.dTime = dTime || 0;\n\n // lerp\n this.sPercent = sPercent || 0;\n this.dLevel =\n typeof sPercent !== 'undefined'\n ? sPercent * (this.aLevel - this.rLevel) + this.rLevel\n : 0;\n\n this.rTime = rTime || 0;\n\n // also set time constants for ramp\n this._setRampAD(aTime, dTime);\n };\n\n /**\n * Set max (attackLevel) and min (releaseLevel) of envelope.\n *\n * @method setRange\n * @for p5.Envelope\n * @param {Number} aLevel attack level (defaults to 1)\n * @param {Number} rLevel release level (defaults to 0)\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * triOsc.start();\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.setRange = function (aLevel, rLevel) {\n this.aLevel = aLevel || 1;\n this.rLevel = rLevel || 0;\n\n // not sure if this belongs here:\n\n // {Number} [dLevel] decay/sustain level (optional)\n // if (typeof(dLevel) !== 'undefined') {\n // this.dLevel = dLevel\n // } else if (this.sPercent) {\n // this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;\n // }\n };\n\n // private (undocumented) method called when ADSR is set to set time constants for ramp\n //\n // Set the \n // time constants for simple exponential ramps.\n // The larger the time constant value, the slower the\n // transition will be.\n //\n // method _setRampAD\n // param {Number} attackTimeConstant attack time constant\n // param {Number} decayTimeConstant decay time constant\n //\n p5.Envelope.prototype._setRampAD = function (t1, t2) {\n this._rampAttackTime = this.checkExpInput(t1);\n this._rampDecayTime = this.checkExpInput(t2);\n\n var TCDenominator = 1.0;\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(\n 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)\n );\n this._rampAttackTC = t1 / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = t2 / this.checkExpInput(TCDenominator);\n };\n\n // private method\n p5.Envelope.prototype.setRampPercentages = function (p1, p2) {\n //set the percentages that the simple exponential ramps go to\n this._rampHighPercentage = this.checkExpInput(p1);\n this._rampLowPercentage = this.checkExpInput(p2);\n var TCDenominator = 1.0;\n //now re-compute the time constants based on those percentages\n /// Aatish Bhatia's calculation for time constant for rise(to adjust 1/1-e calculation to any percentage)\n TCDenominator = Math.log(\n 1.0 / this.checkExpInput(1.0 - this._rampHighPercentage)\n );\n this._rampAttackTC =\n this._rampAttackTime / this.checkExpInput(TCDenominator);\n TCDenominator = Math.log(1.0 / this._rampLowPercentage);\n this._rampDecayTC = this._rampDecayTime / this.checkExpInput(TCDenominator);\n };\n\n /**\n * Assign a parameter to be controlled by this envelope.\n * If a p5.Sound object is given, then the p5.Envelope will control its\n * output gain. If multiple inputs are provided, the env will\n * control all of them.\n *\n * @method setInput\n * @for p5.Envelope\n * @param {Object} [...inputs] A p5.sound object or\n * Web Audio Param.\n */\n p5.Envelope.prototype.setInput = function () {\n for (var i = 0; i < arguments.length; i++) {\n this.connect(arguments[i]);\n }\n };\n\n /**\n * Set whether the envelope ramp is linear (default) or exponential.\n * Exponential ramps can be useful because we perceive amplitude\n * and frequency logarithmically.\n *\n * @method setExp\n * @for p5.Envelope\n * @param {Boolean} isExp true is exponential, false is linear\n */\n p5.Envelope.prototype.setExp = function (isExp) {\n this.isExponential = isExp;\n };\n\n //helper method to protect against zero values being sent to exponential functions\n p5.Envelope.prototype.checkExpInput = function (value) {\n if (value <= 0) {\n value = 0.00000001;\n }\n return value;\n };\n\n /**\n *

Play tells the envelope to start acting on a given input.\n * If the input is a p5.sound object (i.e. AudioIn, Oscillator,\n * SoundFile), then Envelope will control its output volume.\n * Envelopes can also be used to control any \n * Web Audio Audio Param.

\n *\n * @method play\n * @for p5.Envelope\n * @param {Object} unit A p5.sound object or\n * Web Audio Param.\n * @param {Number} [startTime] time from now (in seconds) at which to play\n * @param {Number} [sustainTime] time to sustain before releasing the envelope\n * @example\n *
\n * let attackLevel = 1.0;\n * let releaseLevel = 0;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.2;\n * let releaseTime = 0.5;\n *\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playEnv);\n *\n * env = new p5.Envelope();\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.amp(env);\n * triOsc.freq(220);\n * triOsc.start();\n * }\n *\n * function draw() {\n * background(220);\n * text('tap here to play', 5, 20);\n * attackTime = map(mouseX, 0, width, 0, 1.0);\n * attackLevel = map(mouseY, height, 0, 0, 1.0);\n * text('attack time: ' + attackTime, 5, height - 40);\n * text('attack level: ' + attackLevel, 5, height - 20);\n * }\n *\n * function playEnv() {\n * // ensure that audio is enabled\n * userStartAudio();\n *\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(attackLevel, releaseLevel);\n * env.play();\n * }\n *
\n */\n p5.Envelope.prototype.play = function (unit, secondsFromNow, susTime) {\n var tFromNow = secondsFromNow || 0;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n this.triggerAttack(unit, tFromNow);\n\n this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + ~~susTime);\n };\n\n /**\n * Trigger the Attack, and Decay portion of the Envelope.\n * Similar to holding down a key on a piano, but it will\n * hold the sustain level until you let go. Input can be\n * any p5.sound object, or a \n * Web Audio Param.\n *\n * @method triggerAttack\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time from now (in seconds)\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerAttack = function (unit, secondsFromNow) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n this.lastAttack = t;\n this.wasTriggered = true;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(valToSet),\n t\n );\n } else {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // after each ramp completes, cancel scheduled values\n // (so they can be overridden in case env has been re-triggered)\n // then, set current value (with linearRamp to avoid click)\n // then, schedule the next automation...\n\n // attack\n t += this.aTime;\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.aLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.aLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // decay to decay level (if using ADSR, then decay level == sustain level)\n t += this.dTime;\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.dLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.dLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n };\n\n /**\n * Trigger the Release of the Envelope. This is similar to releasing\n * the key on a piano and letting the sound fade according to the\n * release level and release time.\n *\n * @method triggerRelease\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow time to trigger the release\n * @example\n *
\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let susPercent = 0.3;\n * let releaseTime = 0.4;\n * let env, triOsc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * textSize(10);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n * env.setRange(1.0, 0.0);\n * triOsc = new p5.Oscillator('triangle');\n * triOsc.freq(220);\n *\n * cnv.mousePressed(envAttack);\n * }\n *\n * function envAttack() {\n * background(0, 255, 255);\n * text('release to release', width/2, height/2);\n *\n * // ensures audio is enabled. See also: `userStartAudio`\n * triOsc.start();\n *\n * env.triggerAttack(triOsc);\n * }\n *\n * function mouseReleased() {\n * background(220);\n * text('tap to triggerAttack', width/2, height/2);\n *\n * env.triggerRelease(triOsc);\n * }\n *
\n */\n p5.Envelope.prototype.triggerRelease = function (unit, secondsFromNow) {\n // only trigger a release if an attack was triggered\n if (!this.wasTriggered) {\n // this currently causes a bit of trouble:\n // if a later release has been scheduled (via the play function)\n // a new earlier release won't interrupt it, because\n // this.wasTriggered has already been set to false.\n // If we want new earlier releases to override, then we need to\n // keep track of the last release time, and if the new release time is\n // earlier, then use it.\n return;\n }\n\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n // get and set value (with linear or exponential ramp) to anchor automation\n var valToSet = this.control.getValueAtTime(t);\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(valToSet),\n t\n );\n } else {\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n // release\n t += this.rTime;\n\n if (this.isExponential === true) {\n this.control.exponentialRampToValueAtTime(\n this.checkExpInput(this.rLevel),\n t\n );\n valToSet = this.checkExpInput(this.control.getValueAtTime(t));\n this.control.cancelScheduledValues(t);\n this.control.exponentialRampToValueAtTime(valToSet, t);\n } else {\n this.control.linearRampToValueAtTime(this.rLevel, t);\n valToSet = this.control.getValueAtTime(t);\n this.control.cancelScheduledValues(t);\n this.control.linearRampToValueAtTime(valToSet, t);\n }\n\n this.wasTriggered = false;\n };\n\n /**\n * Exponentially ramp to a value using the first two\n * values from setADSR(attackTime, decayTime)\n * as \n * time constants for simple exponential ramps.\n * If the value is higher than current value, it uses attackTime,\n * while a decrease uses decayTime.\n *\n * @method ramp\n * @for p5.Envelope\n * @param {Object} unit p5.sound Object or Web Audio Param\n * @param {Number} secondsFromNow When to trigger the ramp\n * @param {Number} v Target value\n * @param {Number} [v2] Second target value\n * @example\n *
\n * let env, osc, amp;\n *\n * let attackTime = 0.001;\n * let decayTime = 0.2;\n * let attackLevel = 1;\n * let decayLevel = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * fill(0,255,0);\n * noStroke();\n *\n * env = new p5.Envelope();\n * env.setADSR(attackTime, decayTime);\n * osc = new p5.Oscillator();\n * osc.amp(env);\n * amp = new p5.Amplitude();\n *\n * cnv.mousePressed(triggerRamp);\n * }\n *\n * function triggerRamp() {\n * // ensures audio is enabled. See also: `userStartAudio`\n * osc.start();\n *\n * env.ramp(osc, 0, attackLevel, decayLevel);\n * }\n *\n * function draw() {\n * background(20);\n * text('tap to play', 10, 20);\n * let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n * rect(0, height, width, -h);\n * }\n *
\n */\n p5.Envelope.prototype.ramp = function (unit, secondsFromNow, v1, v2) {\n var now = p5sound.audiocontext.currentTime;\n var tFromNow = secondsFromNow || 0;\n var t = now + tFromNow;\n var destination1 = this.checkExpInput(v1);\n var destination2 =\n typeof v2 !== 'undefined' ? this.checkExpInput(v2) : undefined;\n\n // connect env to unit if not already connected\n if (unit) {\n if (this.connection !== unit) {\n this.connect(unit);\n }\n }\n\n //get current value\n var currentVal = this.checkExpInput(this.control.getValueAtTime(t));\n // this.control.cancelScheduledValues(t);\n\n //if it's going up\n if (destination1 > currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampAttackTC);\n t += this._rampAttackTime;\n }\n\n //if it's going down\n else if (destination1 < currentVal) {\n this.control.setTargetAtTime(destination1, t, this._rampDecayTC);\n t += this._rampDecayTime;\n }\n\n // Now the second part of envelope begins\n if (destination2 === undefined) return;\n\n //if it's going up\n if (destination2 > destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampAttackTC);\n }\n\n //if it's going down\n else if (destination2 < destination1) {\n this.control.setTargetAtTime(destination2, t, this._rampDecayTC);\n }\n };\n\n p5.Envelope.prototype.connect = function (unit) {\n this.connection = unit;\n\n // assume we're talking about output gain\n // unless given a different audio param\n if (\n unit instanceof p5.Oscillator ||\n unit instanceof p5.SoundFile ||\n unit instanceof p5.AudioIn ||\n unit instanceof p5.Reverb ||\n unit instanceof p5.Noise ||\n unit instanceof p5.Filter ||\n unit instanceof p5.Delay\n ) {\n unit = unit.output.gain;\n }\n if (unit instanceof AudioParam) {\n //set the initial value\n unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n }\n if (unit instanceof p5.Signal) {\n unit.setValue(0);\n }\n this.output.connect(unit);\n };\n\n p5.Envelope.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n // Signal Math\n\n /**\n * Add a value to the p5.Oscillator's output amplitude,\n * and return the oscillator. Calling this method\n * again will override the initial add() with new values.\n *\n * @method add\n * @for p5.Envelope\n * @param {Number} number Constant number to add\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.add = function (num) {\n var add = new Add(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n };\n\n /**\n * Multiply the p5.Envelope's output amplitude\n * by a fixed value. Calling this method\n * again will override the initial mult() with new values.\n *\n * @method mult\n * @for p5.Envelope\n * @param {Number} number Constant number to multiply\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.mult = function (num) {\n var mult = new Mult(num);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n };\n\n /**\n * Scale this envelope's amplitude values to a given\n * range, and return the envelope. Calling this method\n * again will override the initial scale() with new values.\n *\n * @method scale\n * @for p5.Envelope\n * @param {Number} inMin input range minumum\n * @param {Number} inMax input range maximum\n * @param {Number} outMin input range minumum\n * @param {Number} outMax input range maximum\n * @return {p5.Envelope} Envelope Returns this envelope\n * with scaled output\n */\n p5.Envelope.prototype.scale = function (inMin, inMax, outMin, outMax) {\n var scale = new Scale(inMin, inMax, outMin, outMax);\n var thisChain = this.mathOps.length;\n var nextChain = this.output;\n return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n };\n\n // get rid of the oscillator\n p5.Envelope.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.disconnect();\n if (this.control) {\n this.control.dispose();\n this.control = null;\n }\n for (var i = 1; i < this.mathOps.length; i++) {\n this.mathOps[i].dispose();\n }\n };\n\n // Different name for backwards compatibility, replicates p5.Envelope class\n p5.Env = function (t1, l1, t2, l2, t3, l3) {\n console.warn(\n 'WARNING: p5.Env is now deprecated and may be removed in future versions. ' +\n 'Please use the new p5.Envelope instead.'\n );\n p5.Envelope.call(this, t1, l1, t2, l2, t3, l3);\n };\n p5.Env.prototype = Object.create(p5.Envelope.prototype);\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n require('oscillator');\n\n /**\n * Creates a Pulse object, an oscillator that implements\n * Pulse Width Modulation.\n * The pulse is created with two oscillators.\n * Accepts a parameter for frequency, and to set the\n * width between the pulses. See \n * p5.Oscillator for a full list of methods.\n *\n * @class p5.Pulse\n * @extends p5.Oscillator\n * @constructor\n * @param {Number} [freq] Frequency in oscillations per second (Hz)\n * @param {Number} [w] Width between the pulses (0 to 1.0,\n * defaults to 0)\n * @example\n *
\n * let pulse;\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startPulse);\n * background(220);\n *\n * pulse = new p5.Pulse();\n * pulse.amp(0.5);\n * pulse.freq(220);\n * }\n * function startPulse() {\n * pulse.start();\n * pulse.amp(0.5, 0.02);\n * }\n * function mouseReleased() {\n * pulse.amp(0, 0.2);\n * }\n * function draw() {\n * background(220);\n * text('tap to play', 5, 20, width - 20);\n * let w = map(mouseX, 0, width, 0, 1);\n * w = constrain(w, 0, 1);\n * pulse.width(w);\n * text('pulse width: ' + w, 5, height - 20);\n * }\n *
\n */\n p5.Pulse = function (freq, w) {\n p5.Oscillator.call(this, freq, 'sawtooth');\n\n // width of PWM, should be betw 0 to 1.0\n this.w = w || 0;\n\n // create a second oscillator with inverse frequency\n this.osc2 = new p5.SawOsc(freq);\n\n // create a delay node\n this.dNode = p5sound.audiocontext.createDelay();\n\n // dc offset\n this.dcOffset = createDCOffset();\n this.dcGain = p5sound.audiocontext.createGain();\n this.dcOffset.connect(this.dcGain);\n this.dcGain.connect(this.output);\n // set delay time based on PWM width\n this.f = freq || 440;\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n\n // disconnect osc2 and connect it to delay, which is connected to output\n this.osc2.disconnect();\n this.osc2.panner.disconnect();\n this.osc2.amp(-1); // inverted amplitude\n this.osc2.output.connect(this.dNode);\n this.dNode.connect(this.output);\n\n this.output.gain.value = 1;\n this.output.connect(this.panner);\n };\n\n p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set the width of a Pulse object (an oscillator that implements\n * Pulse Width Modulation).\n *\n * @method width\n * @param {Number} [width] Width between the pulses (0 to 1.0,\n * defaults to 0)\n */\n p5.Pulse.prototype.width = function (w) {\n if (typeof w === 'number') {\n if (w <= 1.0 && w >= 0.0) {\n this.w = w;\n // set delay time based on PWM width\n\n // var mW = map(this.w, 0, 1.0, 0, 1/this.f);\n var mW = this.w / this.oscillator.frequency.value;\n this.dNode.delayTime.value = mW;\n }\n\n this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n } else {\n w.connect(this.dNode.delayTime);\n var sig = new p5.SignalAdd(-0.5);\n sig.setInput(w);\n sig = sig.mult(-1);\n sig = sig.mult(1.7);\n sig.connect(this.dcGain.gain);\n }\n };\n\n p5.Pulse.prototype.start = function (f, time) {\n var now = p5sound.audiocontext.currentTime;\n var t = time || 0;\n if (!this.started) {\n var freq = f || this.f;\n var type = this.oscillator.type;\n this.oscillator = p5sound.audiocontext.createOscillator();\n this.oscillator.frequency.setValueAtTime(freq, now);\n this.oscillator.type = type;\n this.oscillator.connect(this.output);\n this.oscillator.start(t + now);\n\n // set up osc2\n this.osc2.oscillator = p5sound.audiocontext.createOscillator();\n this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);\n this.osc2.oscillator.type = type;\n this.osc2.oscillator.connect(this.osc2.output);\n this.osc2.start(t + now);\n this.freqNode = [\n this.oscillator.frequency,\n this.osc2.oscillator.frequency,\n ];\n\n // start dcOffset, too\n this.dcOffset = createDCOffset();\n this.dcOffset.connect(this.dcGain);\n this.dcOffset.start(t + now);\n\n // if LFO connections depend on these oscillators\n if (this.mods !== undefined && this.mods.frequency !== undefined) {\n this.mods.frequency.connect(this.freqNode[0]);\n this.mods.frequency.connect(this.freqNode[1]);\n }\n this.started = true;\n this.osc2.started = true;\n }\n };\n\n p5.Pulse.prototype.stop = function (time) {\n if (this.started) {\n var t = time || 0;\n var now = p5sound.audiocontext.currentTime;\n this.oscillator.stop(t + now);\n if (this.osc2.oscillator) {\n this.osc2.oscillator.stop(t + now);\n }\n this.dcOffset.stop(t + now);\n this.started = false;\n this.osc2.started = false;\n }\n };\n\n p5.Pulse.prototype.freq = function (val, rampTime = 0, tFromNow = 0) {\n if (typeof val === 'number') {\n this.f = val;\n var now = p5sound.audiocontext.currentTime;\n var currentFreq = this.oscillator.frequency.value;\n this.oscillator.frequency.cancelScheduledValues(now);\n this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n this.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n this.osc2.oscillator.frequency.cancelScheduledValues(now);\n this.osc2.oscillator.frequency.setValueAtTime(\n currentFreq,\n now + tFromNow\n );\n this.osc2.oscillator.frequency.exponentialRampToValueAtTime(\n val,\n tFromNow + rampTime + now\n );\n\n if (this.freqMod) {\n this.freqMod.output.disconnect();\n this.freqMod = null;\n }\n } else if (val.output) {\n val.output.disconnect();\n val.output.connect(this.oscillator.frequency);\n val.output.connect(this.osc2.oscillator.frequency);\n this.freqMod = val;\n }\n };\n\n // inspiration: http://webaudiodemos.appspot.com/oscilloscope/\n function createDCOffset() {\n var ac = p5sound.audiocontext;\n var buffer = ac.createBuffer(1, 2048, ac.sampleRate);\n var data = buffer.getChannelData(0);\n for (var i = 0; i < 2048; i++) data[i] = 1.0;\n var bufferSource = ac.createBufferSource();\n bufferSource.buffer = buffer;\n bufferSource.loop = true;\n return bufferSource;\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // generate noise buffers\n const _whiteNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var whiteBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = whiteBuffer.getChannelData(0);\n for (var i = 0; i < bufferSize; i++) {\n noiseData[i] = Math.random() * 2 - 1;\n }\n whiteBuffer.type = 'white';\n return whiteBuffer;\n })();\n\n const _pinkNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var pinkBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = pinkBuffer.getChannelData(0);\n var b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.969 * b2 + white * 0.153852;\n b3 = 0.8665 * b3 + white * 0.3104856;\n b4 = 0.55 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.016898;\n noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n noiseData[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n pinkBuffer.type = 'pink';\n return pinkBuffer;\n })();\n\n const _brownNoiseBuffer = (function () {\n var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n var brownBuffer = p5sound.audiocontext.createBuffer(\n 1,\n bufferSize,\n p5sound.audiocontext.sampleRate\n );\n var noiseData = brownBuffer.getChannelData(0);\n var lastOut = 0.0;\n for (var i = 0; i < bufferSize; i++) {\n var white = Math.random() * 2 - 1;\n noiseData[i] = (lastOut + 0.02 * white) / 1.02;\n lastOut = noiseData[i];\n noiseData[i] *= 3.5;\n }\n brownBuffer.type = 'brown';\n return brownBuffer;\n })();\n\n /**\n * Noise is a type of oscillator that generates a buffer with random values.\n *\n * @class p5.Noise\n * @extends p5.Oscillator\n * @constructor\n * @param {String} type Type of noise can be 'white' (default),\n * 'brown' or 'pink'.\n */\n p5.Noise = function (type) {\n var assignType;\n p5.Oscillator.call(this);\n delete this.f;\n delete this.freq;\n delete this.oscillator;\n\n if (type === 'brown') {\n assignType = _brownNoiseBuffer;\n } else if (type === 'pink') {\n assignType = _pinkNoiseBuffer;\n } else {\n assignType = _whiteNoiseBuffer;\n }\n this.buffer = assignType;\n };\n\n p5.Noise.prototype = Object.create(p5.Oscillator.prototype);\n\n /**\n * Set type of noise to 'white', 'pink' or 'brown'.\n * White is the default.\n *\n * @method setType\n * @param {String} [type] 'white', 'pink' or 'brown'\n */\n p5.Noise.prototype.setType = function (type) {\n switch (type) {\n case 'white':\n this.buffer = _whiteNoiseBuffer;\n break;\n case 'pink':\n this.buffer = _pinkNoiseBuffer;\n break;\n case 'brown':\n this.buffer = _brownNoiseBuffer;\n break;\n default:\n this.buffer = _whiteNoiseBuffer;\n }\n if (this.started) {\n var now = p5sound.audiocontext.currentTime;\n this.stop(now);\n this.start(now + 0.01);\n }\n };\n\n p5.Noise.prototype.getType = function () {\n return this.buffer.type;\n };\n\n p5.Noise.prototype.start = function () {\n if (this.started) {\n this.stop();\n }\n this.noise = p5sound.audiocontext.createBufferSource();\n this.noise.buffer = this.buffer;\n this.noise.loop = true;\n this.noise.connect(this.output);\n var now = p5sound.audiocontext.currentTime;\n this.noise.start(now);\n this.started = true;\n };\n\n p5.Noise.prototype.stop = function () {\n var now = p5sound.audiocontext.currentTime;\n if (this.noise) {\n this.noise.stop(now);\n this.started = false;\n }\n };\n\n p5.Noise.prototype.dispose = function () {\n var now = p5sound.audiocontext.currentTime;\n\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n if (this.noise) {\n this.noise.disconnect();\n this.stop(now);\n }\n if (this.output) {\n this.output.disconnect();\n }\n if (this.panner) {\n this.panner.disconnect();\n }\n this.output = null;\n this.panner = null;\n this.buffer = null;\n this.noise = null;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // an array of input sources\n p5sound.inputSources = [];\n\n /**\n *

Get audio from an input, i.e. your computer's microphone.

\n *\n *

Turn the mic on/off with the start() and stop() methods. When the mic\n * is on, its volume can be measured with getLevel or by connecting an\n * FFT object.

\n *\n *

If you want to hear the AudioIn, use the .connect() method.\n * AudioIn does not connect to p5.sound output by default to prevent\n * feedback.

\n *\n *

Note: This uses the getUserMedia/\n * Stream API, which is not supported by certain browsers. Access in Chrome browser\n * is limited to localhost and https, but access over http may be limited.

\n *\n * @class p5.AudioIn\n * @constructor\n * @param {Function} [errorCallback] A function to call if there is an error\n * accessing the AudioIn. For example,\n * Safari and iOS devices do not\n * currently allow microphone access.\n * @example\n *
\n * let mic;\n *\n * function setup(){\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(userStartAudio);\n * textAlign(CENTER);\n * mic = new p5.AudioIn();\n * mic.start();\n * }\n *\n * function draw(){\n * background(0);\n * fill(255);\n * text('tap to start', width/2, 20);\n *\n * micLevel = mic.getLevel();\n * let y = height - micLevel * height;\n * ellipse(width/2, y, 10, 10);\n * }\n *
\n */\n p5.AudioIn = function (errorCallback) {\n // set up audio input\n /**\n * @property {GainNode} input\n */\n this.input = p5sound.audiocontext.createGain();\n /**\n * @property {GainNode} output\n */\n this.output = p5sound.audiocontext.createGain();\n\n /**\n * @property {MediaStream|null} stream\n */\n this.stream = null;\n /**\n * @property {MediaStreamAudioSourceNode|null} mediaStream\n */\n this.mediaStream = null;\n /**\n * @property {Number|null} currentSource\n */\n this.currentSource = null;\n\n /**\n * Client must allow browser to access their microphone / audioin source.\n * Default: false. Will become true when the client enables access.\n *\n * @property {Boolean} enabled\n */\n this.enabled = false;\n\n /**\n * Input amplitude, connect to it by default but not to master out\n *\n * @property {p5.Amplitude} amplitude\n */\n this.amplitude = new p5.Amplitude();\n this.output.connect(this.amplitude.input);\n\n if (\n !window.MediaStreamTrack ||\n !window.navigator.mediaDevices ||\n !window.navigator.mediaDevices.getUserMedia\n ) {\n errorCallback\n ? errorCallback()\n : window.alert(\n 'This browser does not support MediaStreamTrack and mediaDevices'\n );\n }\n\n // add to soundArray so we can dispose on close\n p5sound.soundArray.push(this);\n };\n\n /**\n * Start processing audio input. This enables the use of other\n * AudioIn methods like getLevel(). Note that by default, AudioIn\n * is not connected to p5.sound's output. So you won't hear\n * anything unless you use the connect() method.
\n *\n * Certain browsers limit access to the user's microphone. For example,\n * Chrome only allows access from localhost and over https. For this reason,\n * you may want to include an errorCallback—a function that is called in case\n * the browser won't provide mic access.\n *\n * @method start\n * @for p5.AudioIn\n * @param {Function} [successCallback] Name of a function to call on\n * success.\n * @param {Function} [errorCallback] Name of a function to call if\n * there was an error. For example,\n * some browsers do not support\n * getUserMedia.\n */\n p5.AudioIn.prototype.start = function (successCallback, errorCallback) {\n var self = this;\n\n if (this.stream) {\n this.stop();\n }\n\n // set the audio source\n var audioSource = p5sound.inputSources[self.currentSource];\n var constraints = {\n audio: {\n sampleRate: p5sound.audiocontext.sampleRate,\n echoCancellation: false,\n },\n };\n\n // if developers determine which source to use\n if (p5sound.inputSources[this.currentSource]) {\n constraints.audio.deviceId = audioSource.deviceId;\n }\n\n window.navigator.mediaDevices\n .getUserMedia(constraints)\n .then(function (stream) {\n self.stream = stream;\n self.enabled = true;\n // Wrap a MediaStreamSourceNode around the live input\n self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n self.mediaStream.connect(self.output);\n // only send to the Amplitude reader, so we can see it but not hear it.\n self.amplitude.setInput(self.output);\n if (successCallback) successCallback();\n })\n .catch(function (err) {\n if (errorCallback) errorCallback(err);\n else console.error(err);\n });\n };\n\n /**\n * Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\n * If re-starting, the user may be prompted for permission access.\n *\n * @method stop\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.stop = function () {\n if (this.stream) {\n this.stream.getTracks().forEach(function (track) {\n track.stop();\n });\n\n this.mediaStream.disconnect();\n\n delete this.mediaStream;\n delete this.stream;\n }\n };\n\n /**\n * Connect to an audio unit. If no parameter is provided, will\n * connect to the master output (i.e. your speakers).
\n *\n * @method connect\n * @for p5.AudioIn\n * @param {Object} [unit] An object that accepts audio input,\n * such as an FFT\n */\n p5.AudioIn.prototype.connect = function (unit) {\n if (unit) {\n if (unit.hasOwnProperty('input')) {\n this.output.connect(unit.input);\n } else if (unit.hasOwnProperty('analyser')) {\n this.output.connect(unit.analyser);\n } else {\n this.output.connect(unit);\n }\n } else {\n this.output.connect(p5sound.input);\n }\n };\n\n /**\n * Disconnect the AudioIn from all audio units. For example, if\n * connect() had been called, disconnect() will stop sending\n * signal to your speakers.
\n *\n * @method disconnect\n * @for p5.AudioIn\n */\n p5.AudioIn.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n // stay connected to amplitude even if not outputting to p5\n this.output.connect(this.amplitude.input);\n }\n };\n\n /**\n * Read the Amplitude (volume level) of an AudioIn. The AudioIn\n * class contains its own instance of the Amplitude class to help\n * make it easy to get a microphone's volume level. Accepts an\n * optional smoothing value (0.0 < 1.0). NOTE: AudioIn must\n * .start() before using .getLevel().
\n *\n * @method getLevel\n * @for p5.AudioIn\n * @param {Number} [smoothing] Smoothing is 0.0 by default.\n * Smooths values based on previous values.\n * @return {Number} Volume level (between 0.0 and 1.0)\n */\n p5.AudioIn.prototype.getLevel = function (smoothing) {\n if (smoothing) {\n this.amplitude.smoothing = smoothing;\n }\n return this.amplitude.getLevel();\n };\n\n /**\n * Set amplitude (volume) of a mic input between 0 and 1.0.
\n *\n * @method amp\n * @for p5.AudioIn\n * @param {Number} vol between 0 and 1.0\n * @param {Number} [time] ramp time (optional)\n */\n p5.AudioIn.prototype.amp = function (vol, t) {\n if (t) {\n var rampTime = t || 0;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(\n currentVol,\n p5sound.audiocontext.currentTime\n );\n this.output.gain.linearRampToValueAtTime(\n vol,\n rampTime + p5sound.audiocontext.currentTime\n );\n } else {\n this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n }\n };\n\n /**\n * Returns a list of available input sources. This is a wrapper\n * for \n * MediaDevices.enumerateDevices() - Web APIs | MDN\n * and it returns a Promise.\n * @method getSources\n * @for p5.AudioIn\n * @param {Function} [successCallback] This callback function handles the sources when they\n * have been enumerated. The callback function\n * receives the deviceList array as its only argument\n * @param {Function} [errorCallback] This optional callback receives the error\n * message as its argument.\n * @returns {Promise} Returns a Promise that can be used in place of the callbacks, similar\n * to the enumerateDevices() method\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.getSources = function (onSuccess, onError) {\n return new Promise(function (resolve, reject) {\n window.navigator.mediaDevices\n .enumerateDevices()\n .then(function (devices) {\n p5sound.inputSources = devices.filter(function (device) {\n return device.kind === 'audioinput';\n });\n resolve(p5sound.inputSources);\n if (onSuccess) {\n onSuccess(p5sound.inputSources);\n }\n })\n .catch(function (error) {\n reject(error);\n if (onError) {\n onError(error);\n } else {\n console.error(\n 'This browser does not support MediaStreamTrack.getSources()'\n );\n }\n });\n });\n };\n\n /**\n * Set the input source. Accepts a number representing a\n * position in the array returned by getSources().\n * This is only available in browsers that support\n * \n * navigator.mediaDevices.enumerateDevices()\n *\n * @method setSource\n * @for p5.AudioIn\n * @param {number} num position of input source in the array\n * @example\n *
\n * let audioIn;\n *\n * function setup(){\n * text('getting sources...', 0, 20);\n * audioIn = new p5.AudioIn();\n * audioIn.getSources(gotSources);\n * }\n *\n * function gotSources(deviceList) {\n * if (deviceList.length > 0) {\n * //set the source to the first item in the deviceList array\n * audioIn.setSource(0);\n * let currentSource = deviceList[audioIn.currentSource];\n * text('set source to: ' + currentSource.deviceId, 5, 20, width);\n * }\n * }\n *
\n */\n p5.AudioIn.prototype.setSource = function (num) {\n if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n // set the current source\n this.currentSource = num;\n console.log('set source to ', p5sound.inputSources[this.currentSource]);\n } else {\n console.log('unable to set input source');\n }\n\n // restart stream if currently active\n if (this.stream && this.stream.active) {\n this.start();\n }\n };\n\n // private method\n p5.AudioIn.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this.stop();\n\n if (this.output) {\n this.output.disconnect();\n }\n if (this.amplitude) {\n this.amplitude.disconnect();\n }\n delete this.amplitude;\n delete this.output;\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Signal\", \"Tone/signal/Expr\", \n\t\"Tone/signal/EqualPowerGain\", \"Tone/core/Gain\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Tone.Crossfade provides equal power fading between two inputs. \n\t * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n\t *\n\t * @constructor\n\t * @extends {Tone}\n\t * @param {NormalRange} [initialFade=0.5]\n\t * @example\n\t * var crossFade = new Tone.CrossFade(0.5);\n\t * //connect effect A to crossfade from\n\t * //effect output 0 to crossfade input 0\n\t * effectA.connect(crossFade, 0, 0);\n\t * //connect effect B to crossfade from\n\t * //effect output 0 to crossfade input 1\n\t * effectB.connect(crossFade, 0, 1);\n\t * crossFade.fade.value = 0;\n\t * // ^ only effectA is output\n\t * crossFade.fade.value = 1;\n\t * // ^ only effectB is output\n\t * crossFade.fade.value = 0.5;\n\t * // ^ the two signals are mixed equally. \n\t */\t\t\n\tTone.CrossFade = function(initialFade){\n\n\t\tthis.createInsOuts(2, 1);\n\n\t\t/**\n\t\t * Alias for input[0]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.a = this.input[0] = new Tone.Gain();\n\n\t\t/**\n\t\t * Alias for input[1]. \n\t\t * @type {Tone.Gain}\n\t\t */\n\t\tthis.b = this.input[1] = new Tone.Gain();\n\n\t\t/**\n\t\t * \tThe mix between the two inputs. A fade value of 0\n\t\t * \twill output 100% input[0] and \n\t\t * \ta value of 1 will output 100% input[1]. \n\t\t * @type {NormalRange}\n\t\t * @signal\n\t\t */\n\t\tthis.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange);\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerA = new Tone.EqualPowerGain();\n\n\t\t/**\n\t\t * equal power gain cross fade\n\t\t * @private\n\t\t * @type {Tone.EqualPowerGain}\n\t\t */\n\t\tthis._equalPowerB = new Tone.EqualPowerGain();\n\t\t\n\t\t/**\n\t\t * invert the incoming signal\n\t\t * @private\n\t\t * @type {Tone}\n\t\t */\n\t\tthis._invert = new Tone.Expr(\"1 - $0\");\n\n\t\t//connections\n\t\tthis.a.connect(this.output);\n\t\tthis.b.connect(this.output);\n\t\tthis.fade.chain(this._equalPowerB, this.b.gain);\n\t\tthis.fade.chain(this._invert, this._equalPowerA, this.a.gain);\n\t\tthis._readOnly(\"fade\");\n\t};\n\n\tTone.extend(Tone.CrossFade);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.CrossFade} this\n\t */\n\tTone.CrossFade.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._writable(\"fade\");\n\t\tthis._equalPowerA.dispose();\n\t\tthis._equalPowerA = null;\n\t\tthis._equalPowerB.dispose();\n\t\tthis._equalPowerB = null;\n\t\tthis.fade.dispose();\n\t\tthis.fade = null;\n\t\tthis._invert.dispose();\n\t\tthis._invert = null;\n\t\tthis.a.dispose();\n\t\tthis.a = null;\n\t\tthis.b.dispose();\n\t\tthis.b = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.CrossFade;\n});\n","define([\"Tone/core/Tone\", \"Tone/signal/Add\", \"Tone/signal/Subtract\", \"Tone/signal/Multiply\", \n\t\"Tone/signal/GreaterThan\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Abs\", \"Tone/signal/Negate\", \n\t\"Tone/signal/Modulo\", \"Tone/signal/Pow\", \"Tone/signal/AudioToGain\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Evaluate an expression at audio rate.

\n\t * Parsing code modified from https://code.google.com/p/tapdigit/\n\t * Copyright 2011 2012 Ariya Hidayat, New BSD License\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {string} expr the expression to generate\n\t * @example\n\t * //adds the signals from input[0] and input[1].\n\t * var expr = new Tone.Expr(\"$0 + $1\");\n\t */\n\tTone.Expr = function(){\n\n\t\tvar expr = this._replacements(Array.prototype.slice.call(arguments));\n\t\tvar inputCount = this._parseInputs(expr);\n\n\t\t/**\n\t\t * hold onto all of the nodes for disposal\n\t\t * @type {Array}\n\t\t * @private\n\t\t */\n\t\tthis._nodes = [];\n\n\t\t/**\n\t\t * The inputs. The length is determined by the expression. \n\t\t * @type {Array}\n\t\t */\n\t\tthis.input = new Array(inputCount);\n\n\t\t//create a gain for each input\n\t\tfor (var i = 0; i < inputCount; i++){\n\t\t\tthis.input[i] = this.context.createGain();\n\t\t}\n\n\t\t//parse the syntax tree\n\t\tvar tree = this._parseTree(expr);\n\t\t//evaluate the results\n\t\tvar result;\n\t\ttry {\n\t\t\tresult = this._eval(tree);\n\t\t} catch (e){\n\t\t\tthis._disposeNodes();\n\t\t\tthrow new Error(\"Tone.Expr: Could evaluate expression: \"+expr);\n\t\t}\n\n\t\t/**\n\t\t * The output node is the result of the expression\n\t\t * @type {Tone}\n\t\t */\n\t\tthis.output = result;\n\t};\n\n\tTone.extend(Tone.Expr, Tone.SignalBase);\n\n\t//some helpers to cut down the amount of code\n\tfunction applyBinary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\tself._eval(args[1]).connect(op, 0, 1);\n\t\treturn op;\n\t}\n\tfunction applyUnary(Constructor, args, self){\n\t\tvar op = new Constructor();\n\t\tself._eval(args[0]).connect(op, 0, 0);\n\t\treturn op;\n\t}\n\tfunction getNumber(arg){\n\t\treturn arg ? parseFloat(arg) : undefined;\n\t}\n\tfunction literalNumber(arg){\n\t\treturn arg && arg.args ? parseFloat(arg.args) : undefined;\n\t}\n\n\t/*\n\t * the Expressions that Tone.Expr can parse.\n\t *\n\t * each expression belongs to a group and contains a regexp \n\t * for selecting the operator as well as that operators method\n\t * \n\t * @type {Object}\n\t * @private\n\t */\n\tTone.Expr._Expressions = {\n\t\t//values\n\t\t\"value\" : {\n\t\t\t\"signal\" : {\n\t\t\t\tregexp : /^\\d+\\.\\d+|^\\d+/,\n\t\t\t\tmethod : function(arg){\n\t\t\t\t\tvar sig = new Tone.Signal(getNumber(arg));\n\t\t\t\t\treturn sig;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"input\" : {\n\t\t\t\tregexp : /^\\$\\d/,\n\t\t\t\tmethod : function(arg, self){\n\t\t\t\t\treturn self.input[getNumber(arg.substr(1))];\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t//syntactic glue\n\t\t\"glue\" : {\n\t\t\t\"(\" : {\n\t\t\t\tregexp : /^\\(/,\n\t\t\t},\n\t\t\t\")\" : {\n\t\t\t\tregexp : /^\\)/,\n\t\t\t},\n\t\t\t\",\" : {\n\t\t\t\tregexp : /^,/,\n\t\t\t}\n\t\t},\n\t\t//functions\n\t\t\"func\" : {\n\t\t\t\"abs\" : {\n\t\t\t\tregexp : /^abs/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Abs)\n\t\t\t},\n\t\t\t\"mod\" : {\n\t\t\t\tregexp : /^mod/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar modulus = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Modulo(modulus);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"pow\" : {\n\t\t\t\tregexp : /^pow/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar exp = literalNumber(args[1]);\n\t\t\t\t\tvar op = new Tone.Pow(exp);\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"a2g\" : {\n\t\t\t\tregexp : /^a2g/,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\tvar op = new Tone.AudioToGain();\n\t\t\t\t\tself._eval(args[0]).connect(op);\n\t\t\t\t\treturn op;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t//binary expressions\n\t\t\"binary\" : {\n\t\t\t\"+\" : {\n\t\t\t\tregexp : /^\\+/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Add)\n\t\t\t},\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tprecedence : 1,\n\t\t\t\tmethod : function(args, self){\n\t\t\t\t\t//both unary and binary op\n\t\t\t\t\tif (args.length === 1){\n\t\t\t\t\t\treturn applyUnary(Tone.Negate, args, self);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn applyBinary(Tone.Subtract, args, self);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"*\" : {\n\t\t\t\tregexp : /^\\*/,\n\t\t\t\tprecedence : 0,\n\t\t\t\tmethod : applyBinary.bind(this, Tone.Multiply)\n\t\t\t}\n\t\t},\n\t\t//unary expressions\n\t\t\"unary\" : {\n\t\t\t\"-\" : {\n\t\t\t\tregexp : /^\\-/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.Negate)\n\t\t\t},\n\t\t\t\"!\" : {\n\t\t\t\tregexp : /^\\!/,\n\t\t\t\tmethod : applyUnary.bind(this, Tone.NOT)\n\t\t\t},\n\t\t},\n\t};\n\t\t\n\t/**\n\t * @param {string} expr the expression string\n\t * @return {number} the input count\n\t * @private\n\t */\n\tTone.Expr.prototype._parseInputs = function(expr){\n\t\tvar inputArray = expr.match(/\\$\\d/g);\n\t\tvar inputMax = 0;\n\t\tif (inputArray !== null){\n\t\t\tfor (var i = 0; i < inputArray.length; i++){\n\t\t\t\tvar inputNum = parseInt(inputArray[i].substr(1)) + 1;\n\t\t\t\tinputMax = Math.max(inputMax, inputNum);\n\t\t\t}\n\t\t}\n\t\treturn inputMax;\n\t};\n\n\t/**\n\t * @param {Array} args \tan array of arguments\n\t * @return {string} the results of the replacements being replaced\n\t * @private\n\t */\n\tTone.Expr.prototype._replacements = function(args){\n\t\tvar expr = args.shift();\n\t\tfor (var i = 0; i < args.length; i++){\n\t\t\texpr = expr.replace(/\\%/i, args[i]);\n\t\t}\n\t\treturn expr;\n\t};\n\n\t/**\n\t * tokenize the expression based on the Expressions object\n\t * @param {string} expr \n\t * @return {Object} returns two methods on the tokenized list, next and peek\n\t * @private\n\t */\n\tTone.Expr.prototype._tokenize = function(expr){\n\t\tvar position = -1;\n\t\tvar tokens = [];\n\n\t\twhile(expr.length > 0){\n\t\t\texpr = expr.trim();\n\t\t\tvar token = getNextToken(expr);\n\t\t\ttokens.push(token);\n\t\t\texpr = expr.substr(token.value.length);\n\t\t}\n\n\t\tfunction getNextToken(expr){\n\t\t\tfor (var type in Tone.Expr._Expressions){\n\t\t\t\tvar group = Tone.Expr._Expressions[type];\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tvar reg = op.regexp;\n\t\t\t\t\tvar match = expr.match(reg);\n\t\t\t\t\tif (match !== null){\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype : type,\n\t\t\t\t\t\t\tvalue : match[0],\n\t\t\t\t\t\t\tmethod : op.method\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected token \"+expr);\n\t\t}\n\n\t\treturn {\n\t\t\tnext : function(){\n\t\t\t\treturn tokens[++position];\n\t\t\t},\n\t\t\tpeek : function(){\n\t\t\t\treturn tokens[position + 1];\n\t\t\t}\n\t\t};\n\t};\n\n\t/**\n\t * recursively parse the string expression into a syntax tree\n\t * \n\t * @param {string} expr \n\t * @return {Object}\n\t * @private\n\t */\n\tTone.Expr.prototype._parseTree = function(expr){\n\t\tvar lexer = this._tokenize(expr);\n\t\tvar isUndef = this.isUndef.bind(this);\n\n\t\tfunction matchSyntax(token, syn) {\n\t\t\treturn !isUndef(token) && \n\t\t\t\ttoken.type === \"glue\" &&\n\t\t\t\ttoken.value === syn;\n\t\t}\n\n\t\tfunction matchGroup(token, groupName, prec) {\n\t\t\tvar ret = false;\n\t\t\tvar group = Tone.Expr._Expressions[groupName];\n\t\t\tif (!isUndef(token)){\n\t\t\t\tfor (var opName in group){\n\t\t\t\t\tvar op = group[opName];\n\t\t\t\t\tif (op.regexp.test(token.value)){\n\t\t\t\t\t\tif (!isUndef(prec)){\n\t\t\t\t\t\t\tif(op.precedence === prec){\t\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\n\t\tfunction parseExpression(precedence) {\n\t\t\tif (isUndef(precedence)){\n\t\t\t\tprecedence = 5;\n\t\t\t}\n\t\t\tvar expr;\n\t\t\tif (precedence < 0){\n\t\t\t\texpr = parseUnary();\n\t\t\t} else {\n\t\t\t\texpr = parseExpression(precedence-1);\n\t\t\t}\n\t\t\tvar token = lexer.peek();\n\t\t\twhile (matchGroup(token, \"binary\", precedence)) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [\n\t\t\t\t\t\texpr,\n\t\t\t\t\t\tparseExpression(precedence-1)\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\ttoken = lexer.peek();\n\t\t\t}\n\t\t\treturn expr;\n\t\t}\n\n\t\tfunction parseUnary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (matchGroup(token, \"unary\")) {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\texpr = parseUnary();\n\t\t\t\treturn {\n\t\t\t\t\toperator: token.value,\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : [expr]\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn parsePrimary();\n\t\t}\n\n\t\tfunction parsePrimary() {\n\t\t\tvar token, expr;\n\t\t\ttoken = lexer.peek();\n\t\t\tif (isUndef(token)) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Unexpected termination of expression\");\n\t\t\t}\n\t\t\tif (token.type === \"func\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn parseFunctionCall(token);\n\t\t\t}\n\t\t\tif (token.type === \"value\") {\n\t\t\t\ttoken = lexer.next();\n\t\t\t\treturn {\n\t\t\t\t\tmethod : token.method,\n\t\t\t\t\targs : token.value\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (matchSyntax(token, \"(\")) {\n\t\t\t\tlexer.next();\n\t\t\t\texpr = parseExpression();\n\t\t\t\ttoken = lexer.next();\n\t\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\t\tthrow new SyntaxError(\"Expected )\");\n\t\t\t\t}\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\tthrow new SyntaxError(\"Tone.Expr: Parse error, cannot process token \" + token.value);\n\t\t}\n\n\t\tfunction parseFunctionCall(func) {\n\t\t\tvar token, args = [];\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \"(\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ( in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\ttoken = lexer.peek();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\targs = parseArgumentList();\n\t\t\t}\n\t\t\ttoken = lexer.next();\n\t\t\tif (!matchSyntax(token, \")\")) {\n\t\t\t\tthrow new SyntaxError(\"Tone.Expr: Expected ) in a function call \\\"\" + func.value + \"\\\"\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tmethod : func.method,\n\t\t\t\targs : args,\n\t\t\t\tname : name\n\t\t\t};\n\t\t}\n\n\t\tfunction parseArgumentList() {\n\t\t\tvar token, expr, args = [];\n\t\t\twhile (true) {\n\t\t\t\texpr = parseExpression();\n\t\t\t\tif (isUndef(expr)) {\n\t\t\t\t\t// TODO maybe throw exception?\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\targs.push(expr);\n\t\t\t\ttoken = lexer.peek();\n\t\t\t\tif (!matchSyntax(token, \",\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlexer.next();\n\t\t\t}\n\t\t\treturn args;\n\t\t}\n\n\t\treturn parseExpression();\n\t};\n\n\t/**\n\t * recursively evaluate the expression tree\n\t * @param {Object} tree \n\t * @return {AudioNode} the resulting audio node from the expression\n\t * @private\n\t */\n\tTone.Expr.prototype._eval = function(tree){\n\t\tif (!this.isUndef(tree)){\n\t\t\tvar node = tree.method(tree.args, this);\n\t\t\tthis._nodes.push(node);\n\t\t\treturn node;\n\t\t} \n\t};\n\n\t/**\n\t * dispose all the nodes\n\t * @private\n\t */\n\tTone.Expr.prototype._disposeNodes = function(){\n\t\tfor (var i = 0; i < this._nodes.length; i++){\n\t\t\tvar node = this._nodes[i];\n\t\t\tif (this.isFunction(node.dispose)) {\n\t\t\t\tnode.dispose();\n\t\t\t} else if (this.isFunction(node.disconnect)) {\n\t\t\t\tnode.disconnect();\n\t\t\t}\n\t\t\tnode = null;\n\t\t\tthis._nodes[i] = null;\n\t\t}\n\t\tthis._nodes = null;\n\t};\n\n\t/**\n\t * clean up\n\t */\n\tTone.Expr.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._disposeNodes();\n\t};\n\n\treturn Tone.Expr;\n});","define([\"Tone/core/Tone\", \"Tone/signal/GreaterThanZero\", \"Tone/signal/Subtract\", \"Tone/signal/Signal\"], \n\tfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Output 1 if the signal is greater than the value, otherwise outputs 0.\n\t * can compare two signals or a signal and a number. \n\t * \n\t * @constructor\n\t * @extends {Tone.Signal}\n\t * @param {number} [value=0] the value to compare to the incoming signal\n\t * @example\n\t * var gt = new Tone.GreaterThan(2);\n\t * var sig = new Tone.Signal(4).connect(gt);\n\t * //output of gt is equal 1. \n\t */\n\tTone.GreaterThan = function(value){\n\n\t\tthis.createInsOuts(2, 0);\n\t\t\n\t\t/**\n\t\t * subtract the amount from the incoming signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._param = this.input[0] = new Tone.Subtract(value);\n\t\tthis.input[1] = this._param.input[1];\n\n\t\t/**\n\t\t * compare that amount to zero\n\t\t * @type {Tone.GreaterThanZero}\n\t\t * @private\n\t\t */\n\t\tthis._gtz = this.output = new Tone.GreaterThanZero();\n\n\t\t//connect\n\t\tthis._param.connect(this._gtz);\n\t};\n\n\tTone.extend(Tone.GreaterThan, Tone.Signal);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.GreaterThan} this\n\t */\n\tTone.GreaterThan.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._param.dispose();\n\t\tthis._param = null;\n\t\tthis._gtz.dispose();\n\t\tthis._gtz = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.GreaterThan;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/SignalBase\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Return the absolute value of an incoming signal. \n\t * \n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @example\n\t * var signal = new Tone.Signal(-1);\n\t * var abs = new Tone.Abs();\n\t * signal.connect(abs);\n\t * //the output of abs is 1. \n\t */\n\tTone.Abs = function(){\n\t\t/**\n\t\t * @type {Tone.LessThan}\n\t\t * @private\n\t\t */\n\t\tthis._abs = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (val === 0){\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn Math.abs(val);\n\t\t\t}\n\t\t}, 127);\n\t};\n\n\tTone.extend(Tone.Abs, Tone.SignalBase);\n\n\t/**\n\t * dispose method\n\t * @returns {Tone.Abs} this\n\t */\n\tTone.Abs.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._abs.dispose();\n\t\tthis._abs = null;\n\t\treturn this;\n\t}; \n\n\treturn Tone.Abs;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Multiply\", \"Tone/signal/Subtract\"], \nfunction(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus\n\t * values in the NormalRange. \n\t *\n\t * @constructor\n\t * @extends {Tone.SignalBase}\n\t * @param {NormalRange} modulus The modulus to apply.\n\t * @example\n\t * var mod = new Tone.Modulo(0.2)\n\t * var sig = new Tone.Signal(0.5).connect(mod);\n\t * //mod outputs 0.1\n\t */\n\tTone.Modulo = function(modulus){\n\n\t\tthis.createInsOuts(1, 0);\n\n\t\t/**\n\t\t * A waveshaper gets the integer multiple of \n\t\t * the input signal and the modulus.\n\t\t * @private\n\t\t * @type {Tone.WaveShaper}\n\t\t */\n\t\tthis._shaper = new Tone.WaveShaper(Math.pow(2, 16));\n\n\t\t/**\n\t\t * the integer multiple is multiplied by the modulus\n\t\t * @type {Tone.Multiply}\n\t\t * @private\n\t\t */\n\t\tthis._multiply = new Tone.Multiply();\n\n\t\t/**\n\t\t * and subtracted from the input signal\n\t\t * @type {Tone.Subtract}\n\t\t * @private\n\t\t */\n\t\tthis._subtract = this.output = new Tone.Subtract();\n\n\t\t/**\n\t\t * the modulus signal\n\t\t * @type {Tone.Signal}\n\t\t * @private\n\t\t */\n\t\tthis._modSignal = new Tone.Signal(modulus);\n\n\t\t//connections\n\t\tthis.input.fan(this._shaper, this._subtract);\n\t\tthis._modSignal.connect(this._multiply, 0, 0);\n\t\tthis._shaper.connect(this._multiply, 0, 1);\n\t\tthis._multiply.connect(this._subtract, 0, 1);\n\t\tthis._setWaveShaper(modulus);\n\t};\n\n\tTone.extend(Tone.Modulo, Tone.SignalBase);\n\n\t/**\n\t * @param {number} mod the modulus to apply\n\t * @private\n\t */\n\tTone.Modulo.prototype._setWaveShaper = function(mod){\n\t\tthis._shaper.setMap(function(val){\n\t\t\tvar multiple = Math.floor((val + 0.0001) / mod);\n\t\t\treturn multiple;\n\t\t});\n\t};\n\n\t/**\n\t * The modulus value.\n\t * @memberOf Tone.Modulo#\n\t * @type {NormalRange}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Modulo.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._modSignal.value;\n\t\t},\n\t\tset : function(mod){\n\t\t\tthis._modSignal.value = mod;\n\t\t\tthis._setWaveShaper(mod);\n\t\t}\n\t});\n\n\t/**\n\t * clean up\n\t * @returns {Tone.Modulo} this\n\t */\n\tTone.Modulo.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._shaper.dispose();\n\t\tthis._shaper = null;\n\t\tthis._multiply.dispose();\n\t\tthis._multiply = null;\n\t\tthis._subtract.dispose();\n\t\tthis._subtract = null;\n\t\tthis._modSignal.dispose();\n\t\tthis._modSignal = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Modulo;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Pow applies an exponent to the incoming signal. The incoming signal\n\t * must be AudioRange.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. \n\t * @example\n\t * var pow = new Tone.Pow(2);\n\t * var sig = new Tone.Signal(0.5).connect(pow);\n\t * //output of pow is 0.25. \n\t */\n\tTone.Pow = function(exp){\n\n\t\t/**\n\t\t * the exponent\n\t\t * @private\n\t\t * @type {number}\n\t\t */\n\t\tthis._exp = this.defaultArg(exp, 1);\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);\n\t};\n\n\tTone.extend(Tone.Pow, Tone.SignalBase);\n\n\t/**\n\t * The value of the exponent.\n\t * @memberOf Tone.Pow#\n\t * @type {number}\n\t * @name value\n\t */\n\tObject.defineProperty(Tone.Pow.prototype, \"value\", {\n\t\tget : function(){\n\t\t\treturn this._exp;\n\t\t},\n\t\tset : function(exp){\n\t\t\tthis._exp = exp;\n\t\t\tthis._expScaler.setMap(this._expFunc(this._exp));\n\t\t}\n\t});\n\n\n\t/**\n\t * the function which maps the waveshaper\n\t * @param {number} exp\n\t * @return {function}\n\t * @private\n\t */\n\tTone.Pow.prototype._expFunc = function(exp){\n\t\treturn function(val){\n\t\t\treturn Math.pow(Math.abs(val), exp);\n\t\t};\n\t};\n\n\t/**\n\t * Clean up.\n\t * @returns {Tone.Pow} this\n\t */\n\tTone.Pow.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._expScaler.dispose();\n\t\tthis._expScaler = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.Pow;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\", \"Tone/signal/Signal\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. \n\t * See Tone.GainToAudio.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var a2g = new Tone.AudioToGain();\n\t */\n\tTone.AudioToGain = function(){\n\n\t\t/**\n\t\t * @type {WaveShaperNode}\n\t\t * @private\n\t\t */\n\t\tthis._norm = this.input = this.output = new Tone.WaveShaper(function(x){\n\t\t\treturn (x + 1) / 2;\n\t\t});\n\t};\n\n\tTone.extend(Tone.AudioToGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.AudioToGain} this\n\t */\n\tTone.AudioToGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._norm.dispose();\n\t\tthis._norm = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.AudioToGain;\n});","define([\"Tone/core/Tone\", \"Tone/signal/WaveShaper\"], function(Tone){\n\n\t\"use strict\";\n\n\t/**\n\t * @class Convert an incoming signal between 0, 1 to an equal power gain scale.\n\t *\n\t * @extends {Tone.SignalBase}\n\t * @constructor\n\t * @example\n\t * var eqPowGain = new Tone.EqualPowerGain();\n\t */\n\tTone.EqualPowerGain = function(){\n\n\t\t/**\n\t\t * @type {Tone.WaveShaper}\n\t\t * @private\n\t\t */\n\t\tthis._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){\n\t\t\tif (Math.abs(val) < 0.001){\n\t\t\t\t//should output 0 when input is 0\n\t\t\t\treturn 0;\n\t\t\t} else {\n\t\t\t\treturn this.equalPowerScale(val);\n\t\t\t}\n\t\t}.bind(this), 4096);\n\t};\n\n\tTone.extend(Tone.EqualPowerGain, Tone.SignalBase);\n\n\t/**\n\t * clean up\n\t * @returns {Tone.EqualPowerGain} this\n\t */\n\tTone.EqualPowerGain.prototype.dispose = function(){\n\t\tTone.prototype.dispose.call(this);\n\t\tthis._eqPower.dispose();\n\t\tthis._eqPower = null;\n\t\treturn this;\n\t};\n\n\treturn Tone.EqualPowerGain;\n});","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n var EQFilter = require('eqFilter');\n\n /**\n * p5.EQ is an audio effect that performs the function of a multiband\n * audio equalizer. Equalization is used to adjust the balance of\n * frequency compoenents of an audio signal. This process is commonly used\n * in sound production and recording to change the waveform before it reaches\n * a sound output device. EQ can also be used as an audio effect to create\n * interesting distortions by filtering out parts of the spectrum. p5.EQ is\n * built using a chain of Web Audio Biquad Filter Nodes and can be\n * instantiated with 3 or 8 bands. Bands can be added or removed from\n * the EQ by directly modifying p5.EQ.bands (the array that stores filters).\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.EQ\n * @constructor\n * @extends p5.Effect\n * @param {Number} [_eqsize] Constructor will accept 3 or 8, defaults to 3\n * @return {Object} p5.EQ object\n *\n * @example\n *
\n * let eq, soundFile\n * let eqBandIndex = 0;\n * let eqBandNames = ['lows', 'mids', 'highs'];\n *\n * function preload() {\n * soundFormats('mp3', 'ogg');\n * soundFile = loadSound('assets/beat');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(toggleSound);\n *\n * eq = new p5.EQ(eqBandNames.length);\n * soundFile.disconnect();\n * eq.process(soundFile);\n * }\n *\n * function draw() {\n * background(30);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n * text('filtering ', 50, 25);\n *\n * fill(255, 40, 255);\n * textSize(26);\n * text(eqBandNames[eqBandIndex], 50, 55);\n *\n * fill(255);\n * textSize(9);\n *\n * if (!soundFile.isPlaying()) {\n * text('tap to play', 50, 80);\n * } else {\n * text('tap to filter next band', 50, 80)\n * }\n * }\n *\n * function toggleSound() {\n * if (!soundFile.isPlaying()) {\n * soundFile.play();\n * } else {\n * eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n * }\n *\n * for (let i = 0; i < eq.bands.length; i++) {\n * eq.bands[i].gain(0);\n * }\n * // filter the band we want to filter\n * eq.bands[eqBandIndex].gain(-40);\n * }\n *
\n */\n p5.EQ = function (_eqsize) {\n Effect.call(this);\n\n //p5.EQ can be of size (3) or (8), defaults to 3\n _eqsize = _eqsize === 3 || _eqsize === 8 ? _eqsize : 3;\n\n var factor;\n _eqsize === 3 ? (factor = Math.pow(2, 3)) : (factor = 2);\n\n /**\n * The p5.EQ is built with abstracted p5.Filter objects.\n * To modify any bands, use methods of the \n * p5.Filter API, especially `gain` and `freq`.\n * Bands are stored in an array, with indices 0 - 3, or 0 - 7\n * @property {Array} bands\n *\n */\n this.bands = [];\n\n var freq, res;\n for (var i = 0; i < _eqsize; i++) {\n if (i === _eqsize - 1) {\n freq = 21000;\n res = 0.01;\n } else if (i === 0) {\n freq = 100;\n res = 0.1;\n } else if (i === 1) {\n freq = _eqsize === 3 ? 360 * factor : 360;\n res = 1;\n } else {\n freq = this.bands[i - 1].freq() * factor;\n res = 1;\n }\n this.bands[i] = this._newBand(freq, res);\n\n if (i > 0) {\n this.bands[i - 1].connect(this.bands[i].biquad);\n } else {\n this.input.connect(this.bands[i].biquad);\n }\n }\n this.bands[_eqsize - 1].connect(this.output);\n };\n p5.EQ.prototype = Object.create(Effect.prototype);\n\n /**\n * Process an input by connecting it to the EQ\n * @method process\n * @param {Object} src Audio source\n */\n p5.EQ.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n // /**\n // * Set the frequency and gain of each band in the EQ. This method should be\n // * called with 3 or 8 frequency and gain pairs, depending on the size of the EQ.\n // * ex. eq.set(freq0, gain0, freq1, gain1, freq2, gain2);\n // *\n // * @method set\n // * @for p5.EQ\n // * @param {Number} [freq0] Frequency value for band with index 0\n // * @param {Number} [gain0] Gain value for band with index 0\n // * @param {Number} [freq1] Frequency value for band with index 1\n // * @param {Number} [gain1] Gain value for band with index 1\n // * @param {Number} [freq2] Frequency value for band with index 2\n // * @param {Number} [gain2] Gain value for band with index 2\n // * @param {Number} [freq3] Frequency value for band with index 3\n // * @param {Number} [gain3] Gain value for band with index 3\n // * @param {Number} [freq4] Frequency value for band with index 4\n // * @param {Number} [gain4] Gain value for band with index 4\n // * @param {Number} [freq5] Frequency value for band with index 5\n // * @param {Number} [gain5] Gain value for band with index 5\n // * @param {Number} [freq6] Frequency value for band with index 6\n // * @param {Number} [gain6] Gain value for band with index 6\n // * @param {Number} [freq7] Frequency value for band with index 7\n // * @param {Number} [gain7] Gain value for band with index 7\n // */\n p5.EQ.prototype.set = function () {\n if (arguments.length === this.bands.length * 2) {\n for (var i = 0; i < arguments.length; i += 2) {\n this.bands[i / 2].freq(arguments[i]);\n this.bands[i / 2].gain(arguments[i + 1]);\n }\n } else {\n console.error(\n 'Argument mismatch. .set() should be called with ' +\n this.bands.length * 2 +\n ' arguments. (one frequency and gain value pair for each band of the eq)'\n );\n }\n };\n\n /**\n * Add a new band. Creates a p5.Filter and strips away everything but\n * the raw biquad filter. This method returns an abstracted p5.Filter,\n * which can be added to p5.EQ.bands, in order to create new EQ bands.\n * @private\n * @for p5.EQ\n * @method _newBand\n * @param {Number} freq\n * @param {Number} res\n * @return {Object} Abstracted Filter\n */\n p5.EQ.prototype._newBand = function (freq, res) {\n return new EQFilter(freq, res);\n };\n\n p5.EQ.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n if (this.bands) {\n while (this.bands.length > 0) {\n delete this.bands.pop().dispose();\n }\n delete this.bands;\n }\n };\n\n return p5.EQ;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var p5sound = require('master');\n\n /**\n * EQFilter extends p5.Filter with constraints\n * necessary for the p5.EQ\n *\n * @private\n */\n var EQFilter = function (freq, res) {\n Filter.call(this, 'peaking');\n this.disconnect();\n this.set(freq, res);\n this.biquad.gain.value = 0;\n delete this.input;\n delete this.output;\n delete this._drywet;\n delete this.wet;\n };\n EQFilter.prototype = Object.create(Filter.prototype);\n\n EQFilter.prototype.amp = function () {\n console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');\n };\n EQFilter.prototype.drywet = function () {\n console.warn('`drywet()` is not available for p5.EQ bands.');\n };\n EQFilter.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n if (this.biquad) {\n this.biquad.connect(u.input ? u.input : u);\n } else {\n this.output.connect(u.input ? u.input : u);\n }\n };\n\n EQFilter.prototype.disconnect = function () {\n if (this.biquad) {\n this.biquad.disconnect();\n }\n };\n EQFilter.prototype.dispose = function () {\n // remove reference form soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n this.disconnect();\n delete this.biquad;\n };\n\n return EQFilter;\n});\n","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /**\n * Panner3D is based on the \n * Web Audio Spatial Panner Node.\n * This panner is a spatial processing node that allows audio to be positioned\n * and oriented in 3D space.\n *\n * The position is relative to an \n * Audio Context Listener, which can be accessed\n * by p5.soundOut.audiocontext.listener\n *\n *\n * @class p5.Panner3D\n * @constructor\n */\n\n p5.Panner3D = function () {\n Effect.call(this);\n\n /**\n * \n * Web Audio Spatial Panner Node\n *\n * Properties include
\n * [Panning Model](https://www.w3.org/TR/webaudio/#idl-def-PanningModelType)\n * : \"equal power\" or \"HRTF\"
\n * [DistanceModel](https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType)\n * : \"linear\", \"inverse\", or \"exponential\"\n *\n * @property {AudioNode} panner\n *\n */\n this.panner = this.ac.createPanner();\n this.panner.panningModel = 'HRTF';\n this.panner.distanceModel = 'linear';\n this.panner.connect(this.output);\n this.input.connect(this.panner);\n };\n\n p5.Panner3D.prototype = Object.create(Effect.prototype);\n\n /**\n * Connect an audio sorce\n *\n * @method process\n * @for p5.Panner3D\n * @param {Object} src Input source\n */\n p5.Panner3D.prototype.process = function (src) {\n src.connect(this.input);\n };\n /**\n * Set the X,Y,Z position of the Panner\n * @method set\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.set = function (xVal, yVal, zVal, time) {\n this.positionX(xVal, time);\n this.positionY(yVal, time);\n this.positionZ(zVal, time);\n return [\n this.panner.positionX.value,\n this.panner.positionY.value,\n this.panner.positionZ.value,\n ];\n };\n\n /**\n * Getter and setter methods for position coordinates\n * @method positionX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for position coordinates\n * @method positionZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.positionX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.positionX.value = xVal;\n this.panner.positionX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.panner.positionX);\n }\n return this.panner.positionX.value;\n };\n p5.Panner3D.prototype.positionY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.positionY.value = yVal;\n this.panner.positionY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.panner.positionY);\n }\n return this.panner.positionY.value;\n };\n p5.Panner3D.prototype.positionZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.positionZ.value = zVal;\n this.panner.positionZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.positionZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.panner.positionZ);\n }\n return this.panner.positionZ.value;\n };\n\n /**\n * Set the X,Y,Z position of the Panner\n * @method orient\n * @for p5.Panner3D\n * @param {Number} xVal\n * @param {Number} yVal\n * @param {Number} zVal\n * @param {Number} time\n * @return {Array} Updated x, y, z values as an array\n */\n p5.Panner3D.prototype.orient = function (xVal, yVal, zVal, time) {\n this.orientX(xVal, time);\n this.orientY(yVal, time);\n this.orientZ(zVal, time);\n return [\n this.panner.orientationX.value,\n this.panner.orientationY.value,\n this.panner.orientationZ.value,\n ];\n };\n\n /**\n * Getter and setter methods for orient coordinates\n * @method orientX\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientY\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n /**\n * Getter and setter methods for orient coordinates\n * @method orientZ\n * @for p5.Panner3D\n * @return {Number} updated coordinate value\n */\n p5.Panner3D.prototype.orientX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.panner.orientationX.value = xVal;\n this.panner.orientationX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.panner.orientationX);\n }\n return this.panner.orientationX.value;\n };\n p5.Panner3D.prototype.orientY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.panner.orientationY.value = yVal;\n this.panner.orientationY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.panner.orientationY);\n }\n return this.panner.orientationY.value;\n };\n p5.Panner3D.prototype.orientZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.panner.orientationZ.value = zVal;\n this.panner.orientationZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.panner.orientationZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.panner.orientationZ);\n }\n return this.panner.orientationZ.value;\n };\n\n /**\n * Set the rolloff factor and max distance\n * @method setFalloff\n * @for p5.Panner3D\n * @param {Number} [maxDistance]\n * @param {Number} [rolloffFactor]\n */\n p5.Panner3D.prototype.setFalloff = function (maxDistance, rolloffFactor) {\n this.maxDist(maxDistance);\n this.rolloff(rolloffFactor);\n };\n /**\n * Maxium distance between the source and the listener\n * @method maxDist\n * @for p5.Panner3D\n * @param {Number} maxDistance\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.maxDist = function (maxDistance) {\n if (typeof maxDistance === 'number') {\n this.panner.maxDistance = maxDistance;\n }\n return this.panner.maxDistance;\n };\n\n /**\n * How quickly the volume is reduced as the source moves away from the listener\n * @method rollof\n * @for p5.Panner3D\n * @param {Number} rolloffFactor\n * @return {Number} updated value\n */\n p5.Panner3D.prototype.rolloff = function (rolloffFactor) {\n if (typeof rolloffFactor === 'number') {\n this.panner.rolloffFactor = rolloffFactor;\n }\n return this.panner.rolloffFactor;\n };\n\n p5.Panner3D.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.panner) {\n this.panner.disconnect();\n delete this.panner;\n }\n };\n\n return p5.Panner3D;\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // /**\n // * listener is a class that can construct both a Spatial Panner\n // * and a Spatial Listener. The panner is based on the\n // * Web Audio Spatial Panner Node\n // * https://www.w3.org/TR/webaudio/#the-listenernode-interface\n // * This panner is a spatial processing node that allows audio to be positioned\n // * and oriented in 3D space.\n // *\n // * The Listener modifies the properties of the Audio Context Listener.\n // * Both objects types use the same methods. The default is a spatial panner.\n // *\n // * p5.Panner3D - Constructs a Spatial Panner
\n // * p5.Listener3D - Constructs a Spatial Listener
\n // *\n // * @class listener\n // * @constructor\n // * @return {Object} p5.Listener3D Object\n // *\n // * @param {Web Audio Node} listener Web Audio Spatial Panning Node\n // * @param {AudioParam} listener.panningModel \"equal power\" or \"HRTF\"\n // * @param {AudioParam} listener.distanceModel \"linear\", \"inverse\", or \"exponential\"\n // * @param {String} [type] [Specify construction of a spatial panner or listener]\n // */\n\n p5.Listener3D = function (type) {\n this.ac = p5sound.audiocontext;\n this.listener = this.ac.listener;\n };\n\n // /**\n // * Connect an audio sorce\n // * @param {Object} src Input source\n // */\n p5.Listener3D.prototype.process = function (src) {\n src.connect(this.input);\n };\n // /**\n // * Set the X,Y,Z position of the Panner\n // * @param {[Number]} xVal\n // * @param {[Number]} yVal\n // * @param {[Number]} zVal\n // * @param {[Number]} time\n // * @return {[Array]} [Updated x, y, z values as an array]\n // */\n p5.Listener3D.prototype.position = function (xVal, yVal, zVal, time) {\n this.positionX(xVal, time);\n this.positionY(yVal, time);\n this.positionZ(zVal, time);\n return [\n this.listener.positionX.value,\n this.listener.positionY.value,\n this.listener.positionZ.value,\n ];\n };\n\n // /**\n // * Getter and setter methods for position coordinates\n // * @return {Number} [updated coordinate value]\n // */\n p5.Listener3D.prototype.positionX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.positionX.value = xVal;\n this.listener.positionX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.positionX);\n }\n return this.listener.positionX.value;\n };\n p5.Listener3D.prototype.positionY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.positionY.value = yVal;\n this.listener.positionY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.positionY);\n }\n return this.listener.positionY.value;\n };\n p5.Listener3D.prototype.positionZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.positionZ.value = zVal;\n this.listener.positionZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.positionZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.positionZ);\n }\n return this.listener.positionZ.value;\n };\n\n // cannot define method when class definition is commented\n // /**\n // * Overrides the listener orient() method because Listener has slightly\n // * different params. In human terms, Forward vectors are the direction the\n // * nose is pointing. Up vectors are the direction of the top of the head.\n // *\n // * @method orient\n // * @param {Number} xValF Forward vector X direction\n // * @param {Number} yValF Forward vector Y direction\n // * @param {Number} zValF Forward vector Z direction\n // * @param {Number} xValU Up vector X direction\n // * @param {Number} yValU Up vector Y direction\n // * @param {Number} zValU Up vector Z direction\n // * @param {Number} time\n // * @return {Array} All orienation params\n // */\n p5.Listener3D.prototype.orient = function (\n xValF,\n yValF,\n zValF,\n xValU,\n yValU,\n zValU,\n time\n ) {\n if (arguments.length === 3 || arguments.length === 4) {\n time = arguments[3];\n this.orientForward(xValF, yValF, zValF, time);\n } else if (arguments.length === 6 || arguments === 7) {\n this.orientForward(xValF, yValF, zValF);\n this.orientUp(xValU, yValU, zValU, time);\n }\n\n return [\n this.listener.forwardX.value,\n this.listener.forwardY.value,\n this.listener.forwardZ.value,\n this.listener.upX.value,\n this.listener.upY.value,\n this.listener.upZ.value,\n ];\n };\n\n p5.Listener3D.prototype.orientForward = function (xValF, yValF, zValF, time) {\n this.forwardX(xValF, time);\n this.forwardY(yValF, time);\n this.forwardZ(zValF, time);\n\n return [\n this.listener.forwardX,\n this.listener.forwardY,\n this.listener.forwardZ,\n ];\n };\n\n p5.Listener3D.prototype.orientUp = function (xValU, yValU, zValU, time) {\n this.upX(xValU, time);\n this.upY(yValU, time);\n this.upZ(zValU, time);\n\n return [this.listener.upX, this.listener.upY, this.listener.upZ];\n };\n // /**\n // * Getter and setter methods for orient coordinates\n // * @return {Number} [updated coordinate value]\n // */\n p5.Listener3D.prototype.forwardX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.forwardX.value = xVal;\n this.listener.forwardX.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.forwardX);\n }\n return this.listener.forwardX.value;\n };\n p5.Listener3D.prototype.forwardY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.forwardY.value = yVal;\n this.listener.forwardY.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.forwardY);\n }\n return this.listener.forwardY.value;\n };\n p5.Listener3D.prototype.forwardZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.forwardZ.value = zVal;\n this.listener.forwardZ.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.listener.forwardZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.forwardZ);\n }\n return this.listener.forwardZ.value;\n };\n p5.Listener3D.prototype.upX = function (xVal, time) {\n var t = time || 0;\n if (typeof xVal === 'number') {\n this.listener.upX.value = xVal;\n this.listener.upX.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upX.linearRampToValueAtTime(\n xVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (xVal) {\n xVal.connect(this.listener.upX);\n }\n return this.listener.upX.value;\n };\n p5.Listener3D.prototype.upY = function (yVal, time) {\n var t = time || 0;\n if (typeof yVal === 'number') {\n this.listener.upY.value = yVal;\n this.listener.upY.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upY.linearRampToValueAtTime(\n yVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (yVal) {\n yVal.connect(this.listener.upY);\n }\n return this.listener.upY.value;\n };\n p5.Listener3D.prototype.upZ = function (zVal, time) {\n var t = time || 0;\n if (typeof zVal === 'number') {\n this.listener.upZ.value = zVal;\n this.listener.upZ.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n this.listener.upZ.linearRampToValueAtTime(\n zVal,\n this.ac.currentTime + 0.02 + t\n );\n } else if (zVal) {\n zVal.connect(this.listener.upZ);\n }\n return this.listener.upZ.value;\n };\n\n return p5.Listener3D;\n});\n","'use strict';\n\ndefine(function (require) {\n var Filter = require('filter');\n var Effect = require('effect');\n\n /**\n * Delay is an echo effect. It processes an existing sound source,\n * and outputs a delayed version of that sound. The p5.Delay can\n * produce different effects depending on the delayTime, feedback,\n * filter, and type. In the example below, a feedback of 0.5 (the\n * default value) will produce a looping delay that decreases in\n * volume by 50% each repeat. A filter will cut out the high\n * frequencies so that the delay does not sound as piercing as the\n * original source.\n *\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n * @class p5.Delay\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let osc;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * background(220);\n * textAlign(CENTER);\n * text('tap to play', width/2, height/2);\n *\n * osc = new p5.Oscillator('square');\n * osc.amp(0.5);\n * delay = new p5.Delay();\n *\n * // delay.process() accepts 4 parameters:\n * // source, delayTime (in seconds), feedback, filter frequency\n * delay.process(osc, 0.12, .7, 2300);\n *\n * cnv.mousePressed(oscStart);\n * }\n *\n * function oscStart() {\n * osc.start();\n * }\n *\n * function mouseReleased() {\n * osc.stop();\n * }\n *
\n */\n p5.Delay = function () {\n Effect.call(this);\n\n this._split = this.ac.createChannelSplitter(2);\n this._merge = this.ac.createChannelMerger(2);\n\n this._leftGain = this.ac.createGain();\n this._rightGain = this.ac.createGain();\n\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n *\n * @for p5.Delay\n * @property {DelayNode} leftDelay\n */\n this.leftDelay = this.ac.createDelay();\n /**\n * The p5.Delay is built with two\n * \n * Web Audio Delay Nodes, one for each stereo channel.\n * @for p5.Delay\n * @property {DelayNode} rightDelay\n */\n this.rightDelay = this.ac.createDelay();\n\n this._leftFilter = new Filter();\n this._rightFilter = new Filter();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n\n this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n this._rightFilter.biquad.frequency.setValueAtTime(\n 1200,\n this.ac.currentTime\n );\n this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n\n // graph routing\n this.input.connect(this._split);\n this.leftDelay.connect(this._leftGain);\n this.rightDelay.connect(this._rightGain);\n this._leftGain.connect(this._leftFilter.input);\n this._rightGain.connect(this._rightFilter.input);\n this._merge.connect(this.wet);\n\n this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n\n // default routing\n this.setType(0);\n\n this._maxDelay = this.leftDelay.delayTime.maxValue;\n\n // set initial feedback to 0.5\n this.feedback(0.5);\n };\n\n p5.Delay.prototype = Object.create(Effect.prototype);\n /**\n * Add delay to an audio signal according to a set\n * of delay parameters.\n *\n * @method process\n * @for p5.Delay\n * @param {Object} Signal An object that outputs audio\n * @param {Number} [delayTime] Time (in seconds) of the delay/echo.\n * Some browsers limit delayTime to\n * 1 second.\n * @param {Number} [feedback] sends the delay back through itself\n * in a loop that decreases in volume\n * each time.\n * @param {Number} [lowPass] Cutoff frequency. Only frequencies\n * below the lowPass will be part of the\n * delay.\n */\n p5.Delay.prototype.process = function (src, _delayTime, _feedback, _filter) {\n var feedback = _feedback || 0;\n var delayTime = _delayTime || 0;\n if (feedback >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n }\n if (delayTime >= this._maxDelay) {\n throw new Error(\n 'Delay Time exceeds maximum delay time of ' +\n this._maxDelay +\n ' second.'\n );\n }\n\n src.connect(this.input);\n this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n this._leftGain.gain.value = feedback;\n this._rightGain.gain.value = feedback;\n\n if (_filter) {\n this._leftFilter.freq(_filter);\n this._rightFilter.freq(_filter);\n }\n };\n\n /**\n * Set the delay (echo) time, in seconds. Usually this value will be\n * a floating point number between 0.0 and 1.0.\n *\n * @method delayTime\n * @for p5.Delay\n * @param {Number} delayTime Time (in seconds) of the delay\n */\n p5.Delay.prototype.delayTime = function (t) {\n // if t is an audio node...\n if (typeof t !== 'number') {\n t.connect(this.leftDelay.delayTime);\n t.connect(this.rightDelay.delayTime);\n } else {\n this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n }\n };\n\n /**\n * Feedback occurs when Delay sends its signal back through its input\n * in a loop. The feedback amount determines how much signal to send each\n * time through the loop. A feedback greater than 1.0 is not desirable because\n * it will increase the overall output each time through the loop,\n * creating an infinite feedback loop. The default value is 0.5\n *\n * @method feedback\n * @for p5.Delay\n * @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n * Oscillator that can be used to\n * modulate this param\n * @returns {Number} Feedback value\n *\n */\n p5.Delay.prototype.feedback = function (f) {\n // if f is an audio node...\n if (f && typeof f !== 'number') {\n f.connect(this._leftGain.gain);\n f.connect(this._rightGain.gain);\n } else if (f >= 1.0) {\n throw new Error('Feedback value will force a positive feedback loop.');\n } else if (typeof f === 'number') {\n this._leftGain.gain.value = f;\n this._rightGain.gain.value = f;\n }\n\n // return value of feedback\n return this._leftGain.gain.value;\n };\n\n /**\n * Set a lowpass filter frequency for the delay. A lowpass filter\n * will cut off any frequencies higher than the filter frequency.\n *\n * @method filter\n * @for p5.Delay\n * @param {Number|Object} cutoffFreq A lowpass filter will cut off any\n * frequencies higher than the filter frequency.\n * @param {Number|Object} res Resonance of the filter frequency\n * cutoff, or an object (i.e. a p5.Oscillator)\n * that can be used to modulate this parameter.\n * High numbers (i.e. 15) will produce a resonance,\n * low numbers (i.e. .2) will produce a slope.\n */\n p5.Delay.prototype.filter = function (freq, q) {\n this._leftFilter.set(freq, q);\n this._rightFilter.set(freq, q);\n };\n\n /**\n * Choose a preset type of delay. 'pingPong' bounces the signal\n * from the left to the right channel to produce a stereo effect.\n * Any other parameter will revert to the default delay setting.\n *\n * @method setType\n * @for p5.Delay\n * @param {String|Number} type 'pingPong' (1) or 'default' (0)\n */\n p5.Delay.prototype.setType = function (t) {\n if (t === 1) {\n t = 'pingPong';\n }\n this._split.disconnect();\n this._leftFilter.disconnect();\n this._rightFilter.disconnect();\n this._split.connect(this.leftDelay, 0);\n this._split.connect(this.rightDelay, 1);\n switch (t) {\n case 'pingPong':\n this._rightFilter.setType(this._leftFilter.biquad.type);\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.rightDelay);\n this._rightFilter.output.connect(this.leftDelay);\n break;\n default:\n this._leftFilter.output.connect(this._merge, 0, 0);\n this._rightFilter.output.connect(this._merge, 0, 1);\n this._leftFilter.output.connect(this.leftDelay);\n this._rightFilter.output.connect(this.rightDelay);\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the delay effect.\n *\n * @method amp\n * @for p5.Delay\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Delay\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Delay\n */\n\n p5.Delay.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n\n this._split.disconnect();\n this._leftFilter.dispose();\n this._rightFilter.dispose();\n this._merge.disconnect();\n this._leftGain.disconnect();\n this._rightGain.disconnect();\n this.leftDelay.disconnect();\n this.rightDelay.disconnect();\n\n this._split = undefined;\n this._leftFilter = undefined;\n this._rightFilter = undefined;\n this._merge = undefined;\n this._leftGain = undefined;\n this._rightGain = undefined;\n this.leftDelay = undefined;\n this.rightDelay = undefined;\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var CustomError = require('errorHandler');\n var Effect = require('effect');\n\n /**\n * Reverb adds depth to a sound through a large number of decaying\n * echoes. It creates the perception that sound is occurring in a\n * physical space. The p5.Reverb has paramters for Time (how long does the\n * reverb last) and decayRate (how much the sound decays with each echo)\n * that can be set with the .set() or .process() methods. The p5.Convolver\n * extends p5.Reverb allowing you to recreate the sound of actual physical\n * spaces through convolution.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Reverb\n * @extends p5.Effect\n * @constructor\n * @example\n *
\n * let soundFile, reverb;\n * function preload() {\n * soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n *\n * reverb = new p5.Reverb();\n * soundFile.disconnect(); // so we'll only hear reverb...\n *\n * // connect soundFile to reverb, process w/\n * // 3 second reverbTime, decayRate of 2%\n * reverb.process(soundFile, 3, 2);\n * }\n *\n * function draw() {\n * let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n * // 1 = all reverb, 0 = no reverb\n * reverb.drywet(dryWet);\n *\n * background(220);\n * text('tap to play', 10, 20);\n * text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n * }\n *\n * function playSound() {\n * soundFile.play();\n * }\n *
\n */\n\n p5.Reverb = function () {\n Effect.call(this);\n\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n // default params\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n };\n\n p5.Reverb.prototype = Object.create(Effect.prototype);\n\n p5.Reverb.prototype._initConvolverNode = function () {\n this.convolverNode = this.ac.createConvolver();\n this.input.connect(this.convolverNode);\n this.convolverNode.connect(this.wet);\n };\n\n p5.Reverb.prototype._teardownConvolverNode = function () {\n if (this.convolverNode) {\n this.convolverNode.disconnect();\n delete this.convolverNode;\n }\n };\n\n p5.Reverb.prototype._setBuffer = function (audioBuffer) {\n this._teardownConvolverNode();\n this._initConvolverNode();\n this.convolverNode.buffer = audioBuffer;\n };\n /**\n * Connect a source to the reverb, and assign reverb parameters.\n *\n * @method process\n * @for p5.Reverb\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.process = function (src, seconds, decayRate, reverse) {\n src.connect(this.input);\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n /**\n * Set the reverb settings. Similar to .process(), but without\n * assigning a new input.\n *\n * @method set\n * @for p5.Reverb\n * @param {Number} [seconds] Duration of the reverb, in seconds.\n * Min: 0, Max: 10. Defaults to 3.\n * @param {Number} [decayRate] Percentage of decay with each echo.\n * Min: 0, Max: 100. Defaults to 2.\n * @param {Boolean} [reverse] Play the reverb backwards or forwards.\n */\n p5.Reverb.prototype.set = function (seconds, decayRate, reverse) {\n var rebuild = false;\n if (seconds) {\n this._seconds = seconds;\n rebuild = true;\n }\n if (decayRate) {\n this._decay = decayRate;\n }\n if (reverse) {\n this._reverse = reverse;\n }\n if (rebuild) {\n this._buildImpulse();\n }\n };\n\n // DocBlocks for methods inherited from p5.Effect\n /**\n * Set the output level of the reverb effect.\n *\n * @method amp\n * @for p5.Reverb\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Reverb\n * @param {Object} unit\n */\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Reverb\n */\n\n /**\n * Inspired by Simple Reverb by Jordan Santell\n * https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n *\n * Utility function for building an impulse response\n * based on the module parameters.\n *\n * @private\n */\n p5.Reverb.prototype._buildImpulse = function () {\n var rate = this.ac.sampleRate;\n var length = rate * this._seconds;\n var decay = this._decay;\n var impulse = this.ac.createBuffer(2, length, rate);\n var impulseL = impulse.getChannelData(0);\n var impulseR = impulse.getChannelData(1);\n var n, i;\n for (i = 0; i < length; i++) {\n n = this._reverse ? length - i : i;\n impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n }\n this._setBuffer(impulse);\n };\n\n p5.Reverb.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n this._teardownConvolverNode();\n };\n\n // =======================================================================\n // *** p5.Convolver ***\n // =======================================================================\n\n /**\n *

p5.Convolver extends p5.Reverb. It can emulate the sound of real\n * physical spaces through a process called \n * convolution.

\n *\n *

Convolution multiplies any audio input by an \"impulse response\"\n * to simulate the dispersion of sound over time. The impulse response is\n * generated from an audio file that you provide. One way to\n * generate an impulse response is to pop a balloon in a reverberant space\n * and record the echo. Convolution can also be used to experiment with\n * sound.

\n *\n *

Use the method createConvolution(path) to instantiate a\n * p5.Convolver with a path to your impulse response audio file.

\n *\n * @class p5.Convolver\n * @extends p5.Effect\n * @constructor\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call when loading succeeds\n * @param {Function} [errorCallback] function to call if loading fails.\n * This function will receive an error or\n * XMLHttpRequest object with information\n * about what went wrong.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.Convolver = function (path, callback, errorCallback) {\n p5.Reverb.call(this);\n\n /**\n * Internally, the p5.Convolver uses the a\n * \n * Web Audio Convolver Node.\n *\n * @property {ConvolverNode} convolverNode\n */\n this._initConvolverNode();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n\n if (path) {\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n } else {\n // parameters\n this._seconds = 3;\n this._decay = 2;\n this._reverse = false;\n\n this._buildImpulse();\n }\n };\n\n p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n\n p5.prototype.registerPreloadMethod('createConvolver', p5.prototype);\n\n /**\n * Create a p5.Convolver. Accepts a path to a soundfile\n * that will be used to generate an impulse response.\n *\n * @method createConvolver\n * @for p5\n * @param {String} path path to a sound file\n * @param {Function} [callback] function to call if loading is successful.\n * The object will be passed in as the argument\n * to the callback function.\n * @param {Function} [errorCallback] function to call if loading is not successful.\n * A custom error will be passed in as the argument\n * to the callback function.\n * @return {p5.Convolver}\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *
\n */\n p5.prototype.createConvolver = function (path, callback, errorCallback) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n var self = this;\n var cReverb = new p5.Convolver(\n path,\n function (buffer) {\n if (typeof callback === 'function') {\n callback(buffer);\n }\n\n if (typeof self._decrementPreload === 'function') {\n self._decrementPreload();\n }\n },\n errorCallback\n );\n cReverb.impulses = [];\n return cReverb;\n };\n\n /**\n * Private method to load a buffer as an Impulse Response,\n * assign it to the convolverNode, and add to the Array of .impulses.\n *\n * @param {String} path\n * @param {Function} callback\n * @param {Function} errorCallback\n * @private\n */\n p5.Convolver.prototype._loadBuffer = function (\n _path,\n callback,\n errorCallback\n ) {\n var path = p5.prototype._checkFileFormats(_path);\n var self = this;\n var errorTrace = new Error().stack;\n var ac = p5.prototype.getAudioContext();\n\n var request = new XMLHttpRequest();\n request.open('GET', path, true);\n request.responseType = 'arraybuffer';\n\n request.onload = function () {\n if (request.status === 200) {\n // on success loading file:\n ac.decodeAudioData(\n request.response,\n function (buff) {\n var buffer = {};\n var chunks = path.split('/');\n buffer.name = chunks[chunks.length - 1];\n buffer.audioBuffer = buff;\n self.impulses.push(buffer);\n self._setBuffer(buffer.audioBuffer);\n if (callback) {\n callback(buffer);\n }\n },\n // error decoding buffer. \"e\" is undefined in Chrome 11/22/2015\n function () {\n var err = new CustomError('decodeAudioData', errorTrace, self.url);\n var msg = 'AudioContext error at decodeAudioData for ' + self.url;\n if (errorCallback) {\n err.msg = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n );\n }\n // if request status != 200, it failed\n else {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg =\n 'Unable to load ' +\n self.url +\n '. The request status was: ' +\n request.status +\n ' (' +\n request.statusText +\n ')';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n }\n };\n\n // if there is another error, aside from 404...\n request.onerror = function () {\n var err = new CustomError('loadConvolver', errorTrace, self.url);\n var msg =\n 'There was no response from the server at ' +\n self.url +\n '. Check the url and internet connectivity.';\n\n if (errorCallback) {\n err.message = msg;\n errorCallback(err);\n } else {\n console.error(\n msg + '\\n The error stack trace includes: \\n' + err.stack\n );\n }\n };\n request.send();\n };\n\n p5.Convolver.prototype.set = null;\n\n /**\n * Connect a source to the convolver.\n *\n * @method process\n * @for p5.Convolver\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n * @example\n *
\n * let cVerb, sound;\n * function preload() {\n * // We have both MP3 and OGG versions of all sound assets\n * soundFormats('ogg', 'mp3');\n *\n * // Try replacing 'bx-spring' with other soundfiles like\n * // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n * cVerb = createConvolver('assets/bx-spring.mp3');\n *\n * // Try replacing 'Damscray_DancingTiger' with\n * // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n * sound = loadSound('assets/Damscray_DancingTiger.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playSound);\n * background(220);\n * text('tap to play', 20, 20);\n *\n * // disconnect from master output...\n * sound.disconnect();\n *\n * // ...and process with cVerb\n * // so that we only hear the convolution\n * cVerb.process(sound);\n * }\n *\n * function playSound() {\n * sound.play();\n * }\n *\n *
\n */\n p5.Convolver.prototype.process = function (src) {\n src.connect(this.input);\n };\n\n /**\n * If you load multiple impulse files using the .addImpulse method,\n * they will be stored as Objects in this Array. Toggle between them\n * with the toggleImpulse(id) method.\n *\n * @property {Array} impulses\n * @for p5.Convolver\n */\n p5.Convolver.prototype.impulses = [];\n\n /**\n * Load and assign a new Impulse Response to the p5.Convolver.\n * The impulse is added to the .impulses array. Previous\n * impulses can be accessed with the .toggleImpulse(id)\n * method.\n *\n * @method addImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.addImpulse = function (path, callback, errorCallback) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * Similar to .addImpulse, except that the .impulses\n * Array is reset to save memory. A new .impulses\n * array is created with this impulse as the only item.\n *\n * @method resetImpulse\n * @for p5.Convolver\n * @param {String} path path to a sound file\n * @param {Function} callback function (optional)\n * @param {Function} errorCallback function (optional)\n */\n p5.Convolver.prototype.resetImpulse = function (\n path,\n callback,\n errorCallback\n ) {\n // if loading locally without a server\n if (\n window.location.origin.indexOf('file://') > -1 &&\n window.cordova === 'undefined'\n ) {\n alert(\n 'This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS'\n );\n }\n this.impulses = [];\n this._loadBuffer(path, callback, errorCallback);\n };\n\n /**\n * If you have used .addImpulse() to add multiple impulses\n * to a p5.Convolver, then you can use this method to toggle between\n * the items in the .impulses Array. Accepts a parameter\n * to identify which impulse you wish to use, identified either by its\n * original filename (String) or by its position in the .impulses\n * Array (Number).
\n * You can access the objects in the .impulses Array directly. Each\n * Object has two attributes: an .audioBuffer (type:\n * Web Audio \n * AudioBuffer) and a .name, a String that corresponds\n * with the original filename.\n *\n * @method toggleImpulse\n * @for p5.Convolver\n * @param {String|Number} id Identify the impulse by its original filename\n * (String), or by its position in the\n * .impulses Array (Number).\n */\n p5.Convolver.prototype.toggleImpulse = function (id) {\n if (typeof id === 'number' && id < this.impulses.length) {\n this._setBuffer(this.impulses[id].audioBuffer);\n }\n if (typeof id === 'string') {\n for (var i = 0; i < this.impulses.length; i++) {\n if (this.impulses[i].name === id) {\n this._setBuffer(this.impulses[i].audioBuffer);\n break;\n }\n }\n }\n };\n\n p5.Convolver.prototype.dispose = function () {\n p5.Reverb.prototype.dispose.apply(this);\n\n // remove all the Impulse Response buffers\n for (var i in this.impulses) {\n if (this.impulses[i]) {\n this.impulses[i] = null;\n }\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n // https://github.com/TONEnoTONE/Tone.js/\n var Clock = require('Tone/core/Clock');\n\n p5.Metro = function () {\n this.clock = new Clock({\n callback: this.ontick.bind(this),\n });\n this.syncedParts = [];\n this.bpm = 120; // gets overridden by p5.Part\n this._init();\n\n this.prevTick = 0;\n this.tatumTime = 0;\n\n this.tickCallback = function () {};\n };\n\n p5.Metro.prototype.ontick = function (tickTime) {\n var elapsedTime = tickTime - this.prevTick;\n var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n if (elapsedTime - this.tatumTime <= -0.02) {\n return;\n } else {\n // console.log('ok', this.syncedParts[0].phrases[0].name);\n this.prevTick = tickTime;\n\n // for all of the active things on the metro:\n var self = this;\n this.syncedParts.forEach(function (thisPart) {\n if (!thisPart.isPlaying) return;\n thisPart.incrementStep(secondsFromNow);\n // each synced source keeps track of its own beat number\n thisPart.phrases.forEach(function (thisPhrase) {\n var phraseArray = thisPhrase.sequence;\n var bNum = self.metroTicks % phraseArray.length;\n if (\n phraseArray[bNum] !== 0 &&\n (self.metroTicks < phraseArray.length || !thisPhrase.looping)\n ) {\n thisPhrase.callback(secondsFromNow, phraseArray[bNum]);\n }\n });\n });\n this.metroTicks += 1;\n this.tickCallback(secondsFromNow);\n }\n };\n\n p5.Metro.prototype.setBPM = function (bpm, rampTime = 0) {\n var beatTime = 60 / (bpm * this.tatums);\n var now = p5sound.audiocontext.currentTime;\n this.tatumTime = beatTime;\n\n this.clock.frequency.setValueAtTime(this.clock.frequency.value, now);\n this.clock.frequency.linearRampToValueAtTime(bpm, now + rampTime);\n this.bpm = bpm;\n };\n\n p5.Metro.prototype.getBPM = function () {\n return (this.clock.getRate() / this.tatums) * 60;\n };\n\n p5.Metro.prototype._init = function () {\n this.metroTicks = 0;\n // this.setBPM(120);\n };\n\n // clear existing synced parts, add only this one\n p5.Metro.prototype.resetSync = function (part) {\n this.syncedParts = [part];\n };\n\n // push a new synced part to the array\n p5.Metro.prototype.pushSync = function (part) {\n this.syncedParts.push(part);\n };\n\n p5.Metro.prototype.start = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.start(now + t);\n this.setBPM(this.bpm);\n };\n\n p5.Metro.prototype.stop = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n this.clock.stop(now + t);\n };\n\n p5.Metro.prototype.beatLength = function (tatums) {\n this.tatums = 1 / tatums / 4; // lowest possible division of a beat\n };\n});\n","define([\"Tone/core/Tone\", \"Tone/core/Timeline\", \"Tone/type/Type\"], function (Tone) {\n\n\t\"use strict\";\n\n\t/**\n\t * @class A Timeline State. Provides the methods: setStateAtTime(\"state\", time)\n\t * and getValueAtTime(time).\n\t *\n\t * @extends {Tone.Timeline}\n\t * @param {String} initial The initial state of the TimelineState. \n\t * Defaults to undefined\n\t */\n\tTone.TimelineState = function(initial){\n\n\t\tTone.Timeline.call(this);\n\n\t\t/**\n\t\t * The initial state\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._initial = initial;\n\t};\n\n\tTone.extend(Tone.TimelineState, Tone.Timeline);\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {Number} time The time to query.\n\t * @return {String} The name of the state input in setStateAtTime.\n\t */\n\tTone.TimelineState.prototype.getValueAtTime = function(time){\n\t\tvar event = this.get(time);\n\t\tif (event !== null){\n\t\t\treturn event.state;\n\t\t} else {\n\t\t\treturn this._initial;\n\t\t}\n\t};\n\n\t/**\n\t * Returns the scheduled state scheduled before or at\n\t * the given time.\n\t * @param {String} state The name of the state to set.\n\t * @param {Number} time The time to query.\n\t */\n\tTone.TimelineState.prototype.setStateAtTime = function(state, time){\n\t\tthis.add({\n\t\t\t\"state\" : state,\n\t\t\t\"time\" : time\n\t\t});\n\t};\n\n\treturn Tone.TimelineState;\n});","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n var BPM = 120;\n\n /**\n * Set the global tempo, in beats per minute, for all\n * p5.Parts. This method will impact all active p5.Parts.\n *\n * @method setBPM\n * @for p5\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.prototype.setBPM = function (bpm, rampTime) {\n BPM = bpm;\n for (var i in p5sound.parts) {\n if (p5sound.parts[i]) {\n p5sound.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n /**\n *

A phrase is a pattern of musical events over time, i.e.\n * a series of notes and rests.

\n *\n *

Phrases must be added to a p5.Part for playback, and\n * each part can play multiple phrases at the same time.\n * For example, one Phrase might be a kick drum, another\n * could be a snare, and another could be the bassline.

\n *\n *

The first parameter is a name so that the phrase can be\n * modified or deleted later. The callback is a a function that\n * this phrase will call at every step—for example it might be\n * called playNote(value){}. The array determines\n * which value is passed into the callback at each step of the\n * phrase. It can be numbers, an object with multiple numbers,\n * or a zero (0) indicates a rest so the callback won't be called).

\n *\n * @class p5.Phrase\n * @constructor\n * @param {String} name Name so that you can access the Phrase.\n * @param {Function} callback The name of a function that this phrase\n * will call. Typically it will play a sound,\n * and accept two parameters: a time at which\n * to play the sound (in seconds from now),\n * and a value from the sequence array. The\n * time should be passed into the play() or\n * start() method to ensure precision.\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n * @example\n *
\n * let mySound, myPhrase, myPart;\n * let pattern = [1,0,0,2,0,2,0,0];\n *\n * function preload() {\n * mySound = loadSound('assets/beatbox.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * text('tap to play', width/2, height/2);\n * textAlign(CENTER, CENTER);\n *\n * myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n * myPart = new p5.Part();\n * myPart.addPhrase(myPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function onEachStep(time, playbackRate) {\n * mySound.rate(playbackRate);\n * mySound.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n * myPart.start();\n * }\n *
\n */\n p5.Phrase = function (name, callback, sequence) {\n this.phraseStep = 0;\n this.name = name;\n this.callback = callback;\n /**\n * Array of values to pass into the callback\n * at each step of the phrase. Depending on the callback\n * function's requirements, these values may be numbers,\n * strings, or an object with multiple parameters.\n * Zero (0) indicates a rest.\n *\n * @property {Array} sequence\n */\n this.sequence = sequence;\n };\n\n /**\n *

A p5.Part plays back one or more p5.Phrases. Instantiate a part\n * with steps and tatums. By default, each step represents a 1/16th note.

\n *\n *

See p5.Phrase for more about musical timing.

\n *\n * @class p5.Part\n * @constructor\n * @param {Number} [steps] Steps in the part\n * @param {Number} [tatums] Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)\n * @example\n *
\n * let box, drum, myPart;\n * let boxPat = [1,0,0,2,0,2,0,0];\n * let drumPat = [0,1,1,0,2,0,1,0];\n *\n * function preload() {\n * box = loadSound('assets/beatbox.mp3');\n * drum = loadSound('assets/drum.mp3');\n * }\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(playMyPart);\n * background(220);\n * textAlign(CENTER, CENTER);\n * text('tap to play', width/2, height/2);\n *\n * let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n * let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n * myPart = new p5.Part();\n * myPart.addPhrase(boxPhrase);\n * myPart.addPhrase(drumPhrase);\n * myPart.setBPM(60);\n * }\n *\n * function playBox(time, playbackRate) {\n * box.rate(playbackRate);\n * box.play(time);\n * }\n *\n * function playDrum(time, playbackRate) {\n * drum.rate(playbackRate);\n * drum.play(time);\n * }\n *\n * function playMyPart() {\n * userStartAudio();\n *\n * myPart.start();\n * }\n *
\n */\n p5.Part = function (steps, bLength) {\n this.length = steps || 0; // how many beats\n this.partStep = 0;\n this.phrases = [];\n this.isPlaying = false;\n this.noLoop();\n this.tatums = bLength || 0.0625; // defaults to quarter note\n\n this.metro = new p5.Metro();\n this.metro._init();\n this.metro.beatLength(this.tatums);\n this.metro.setBPM(BPM);\n p5sound.parts.push(this);\n this.callback = function () {};\n };\n\n /**\n * Set the tempo of this part, in Beats Per Minute.\n *\n * @method setBPM\n * @for p5.Part\n * @param {Number} BPM Beats Per Minute\n * @param {Number} [rampTime] Seconds from now\n */\n p5.Part.prototype.setBPM = function (tempo, rampTime) {\n this.metro.setBPM(tempo, rampTime);\n };\n\n /**\n * Returns the tempo, in Beats Per Minute, of this part.\n *\n * @method getBPM\n * @for p5.Part\n * @return {Number}\n */\n p5.Part.prototype.getBPM = function () {\n return this.metro.getBPM();\n };\n\n /**\n * Start playback of this part. It will play\n * through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method start\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.start = function (time) {\n if (!this.isPlaying) {\n this.isPlaying = true;\n this.metro.resetSync(this);\n var t = time || 0;\n this.metro.start(t);\n }\n };\n\n /**\n * Loop playback of this part. It will begin\n * looping through all of its phrases at a speed\n * determined by setBPM.\n *\n * @method loop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.loop = function (time) {\n this.looping = true;\n // rest onended function\n this.onended = function () {\n this.partStep = 0;\n };\n var t = time || 0;\n this.start(t);\n };\n\n /**\n * Tell the part to stop looping.\n *\n * @method noLoop\n * @for p5.Part\n */\n p5.Part.prototype.noLoop = function () {\n this.looping = false;\n // rest onended function\n this.onended = function () {\n this.stop();\n };\n };\n\n /**\n * Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.\n *\n * @method stop\n * @for p5.Part\n * @param {Number} [time] seconds from now\n */\n p5.Part.prototype.stop = function (time) {\n this.partStep = 0;\n this.pause(time);\n };\n\n /**\n * Pause the part. Playback will resume\n * from the current step.\n *\n * @method pause\n * @for p5.Part\n * @param {Number} time seconds from now\n */\n p5.Part.prototype.pause = function (time) {\n this.isPlaying = false;\n var t = time || 0;\n this.metro.stop(t);\n };\n\n /**\n * Add a p5.Phrase to this Part.\n *\n * @method addPhrase\n * @for p5.Part\n * @param {p5.Phrase} phrase reference to a p5.Phrase\n */\n p5.Part.prototype.addPhrase = function (name, callback, array) {\n var p;\n if (arguments.length === 3) {\n p = new p5.Phrase(name, callback, array);\n } else if (arguments[0] instanceof p5.Phrase) {\n p = arguments[0];\n } else {\n throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n }\n this.phrases.push(p);\n // reset the length if phrase is longer than part's existing length\n if (p.sequence.length > this.length) {\n this.length = p.sequence.length;\n }\n };\n\n /**\n * Remove a phrase from this part, based on the name it was\n * given when it was created.\n *\n * @method removePhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.removePhrase = function (name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases.splice(i, 1);\n }\n }\n };\n\n /**\n * Get a phrase from this part, based on the name it was\n * given when it was created. Now you can modify its array.\n *\n * @method getPhrase\n * @for p5.Part\n * @param {String} phraseName\n */\n p5.Part.prototype.getPhrase = function (name) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n return this.phrases[i];\n }\n }\n };\n\n /**\n * Find all sequences with the specified name, and replace their patterns with the specified array.\n *\n * @method replaceSequence\n * @for p5.Part\n * @param {String} phraseName\n * @param {Array} sequence Array of values to pass into the callback\n * at each step of the phrase.\n */\n p5.Part.prototype.replaceSequence = function (name, array) {\n for (var i in this.phrases) {\n if (this.phrases[i].name === name) {\n this.phrases[i].sequence = array;\n }\n }\n };\n\n p5.Part.prototype.incrementStep = function (time) {\n if (this.partStep < this.length - 1) {\n this.callback(time);\n this.partStep += 1;\n } else {\n if (!this.looping && this.partStep === this.length - 1) {\n // this.callback(time);\n this.onended();\n }\n }\n };\n\n /**\n * Set the function that will be called at every step. This will clear the previous function.\n *\n * @method onStep\n * @for p5.Part\n * @param {Function} callback The name of the callback\n * you want to fire\n * on every beat/tatum.\n */\n p5.Part.prototype.onStep = function (callback) {\n this.callback = callback;\n };\n\n // ===============\n // p5.Score\n // ===============\n\n /**\n * A Score consists of a series of Parts. The parts will\n * be played back in order. For example, you could have an\n * A part, a B part, and a C part, and play them back in this order\n * new p5.Score(a, a, b, a, c)\n *\n * @class p5.Score\n * @constructor\n * @param {p5.Part} [...parts] One or multiple parts, to be played in sequence.\n */\n p5.Score = function () {\n // for all of the arguments\n this.parts = [];\n this.currentPart = 0;\n\n var thisScore = this;\n for (var i in arguments) {\n if (arguments[i] && this.parts[i]) {\n this.parts[i] = arguments[i];\n this.parts[i].nextPart = this.parts[i + 1];\n this.parts[i].onended = function () {\n thisScore.resetPart(i);\n playNextPart(thisScore);\n };\n }\n }\n this.looping = false;\n };\n\n p5.Score.prototype.onended = function () {\n if (this.looping) {\n // this.resetParts();\n this.parts[0].start();\n } else {\n this.parts[this.parts.length - 1].onended = function () {\n this.stop();\n this.resetParts();\n };\n }\n this.currentPart = 0;\n };\n\n /**\n * Start playback of the score.\n *\n * @method start\n * @for p5.Score\n */\n p5.Score.prototype.start = function () {\n this.parts[this.currentPart].start();\n this.scoreStep = 0;\n };\n\n /**\n * Stop playback of the score.\n *\n * @method stop\n * @for p5.Score\n */\n p5.Score.prototype.stop = function () {\n this.parts[this.currentPart].stop();\n this.currentPart = 0;\n this.scoreStep = 0;\n };\n\n /**\n * Pause playback of the score.\n *\n * @method pause\n * @for p5.Score\n */\n p5.Score.prototype.pause = function () {\n this.parts[this.currentPart].stop();\n };\n\n /**\n * Loop playback of the score.\n *\n * @method loop\n * @for p5.Score\n */\n p5.Score.prototype.loop = function () {\n this.looping = true;\n this.start();\n };\n\n /**\n * Stop looping playback of the score. If it\n * is currently playing, this will go into effect\n * after the current round of playback completes.\n *\n * @method noLoop\n * @for p5.Score\n */\n p5.Score.prototype.noLoop = function () {\n this.looping = false;\n };\n\n p5.Score.prototype.resetParts = function () {\n var self = this;\n this.parts.forEach(function (part) {\n self.resetParts[part];\n });\n };\n\n p5.Score.prototype.resetPart = function (i) {\n this.parts[i].stop();\n this.parts[i].partStep = 0;\n for (var p in this.parts[i].phrases) {\n if (this.parts[i]) {\n this.parts[i].phrases[p].phraseStep = 0;\n }\n }\n };\n\n /**\n * Set the tempo for all parts in the score\n *\n * @method setBPM\n * @for p5.Score\n * @param {Number} BPM Beats Per Minute\n * @param {Number} rampTime Seconds from now\n */\n p5.Score.prototype.setBPM = function (bpm, rampTime) {\n for (var i in this.parts) {\n if (this.parts[i]) {\n this.parts[i].setBPM(bpm, rampTime);\n }\n }\n };\n\n function playNextPart(aScore) {\n aScore.currentPart++;\n if (aScore.currentPart >= aScore.parts.length) {\n aScore.scoreStep = 0;\n aScore.onended();\n } else {\n aScore.scoreStep = 0;\n aScore.parts[aScore.currentPart - 1].stop();\n aScore.parts[aScore.currentPart].start();\n }\n }\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n var Clock = require('Tone/core/Clock');\n\n /**\n * SoundLoop\n *\n * @class p5.SoundLoop\n * @constructor\n *\n * @param {Function} callback this function will be called on each iteration of theloop\n * @param {Number|String} [interval] amount of time (if a number) or beats (if a string, following Tone.Time convention) for each iteration of the loop. Defaults to 1 second.\n *\n * @example\n *
\n * let synth, soundLoop;\n * let notePattern = [60, 62, 64, 67, 69, 72];\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * colorMode(HSB);\n * background(0, 0, 86);\n * text('tap to start/stop', 10, 20);\n *\n * //the looper's callback is passed the timeFromNow\n * //this value should be used as a reference point from\n * //which to schedule sounds\n * let intervalInSeconds = 0.2;\n * soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n *\n * synth = new p5.MonoSynth();\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * if (soundLoop.isPlaying) {\n * soundLoop.stop();\n * } else {\n * // start the loop\n * soundLoop.start();\n * }\n * }\n *\n * function onSoundLoop(timeFromNow) {\n * let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n * let note = midiToFreq(notePattern[noteIndex]);\n * synth.play(note, 0.5, timeFromNow);\n * background(noteIndex * 360 / notePattern.length, 50, 100);\n * }\n *
\n */\n p5.SoundLoop = function (callback, interval) {\n this.callback = callback;\n /**\n * musicalTimeMode uses Tone.Time convention\n * true if string, false if number\n * @property {Boolean} musicalTimeMode\n */\n this.musicalTimeMode = typeof this._interval === 'number' ? false : true;\n\n this._interval = interval || 1;\n\n /**\n * musicalTimeMode variables\n * modify these only when the interval is specified in musicalTime format as a string\n */\n this._timeSignature = 4;\n this._bpm = 60;\n\n this.isPlaying = false;\n\n /**\n * Set a limit to the number of loops to play. defaults to Infinity\n * @property {Number} maxIterations\n */\n this.maxIterations = Infinity;\n var self = this;\n\n this.clock = new Clock({\n callback: function (time) {\n var timeFromNow = time - p5sound.audiocontext.currentTime;\n /**\n * Do not initiate the callback if timeFromNow is < 0\n * This ususually occurs for a few milliseconds when the page\n * is not fully loaded\n *\n * The callback should only be called until maxIterations is reached\n */\n if (timeFromNow > 0 && self.iterations <= self.maxIterations) {\n self.callback(timeFromNow);\n }\n },\n frequency: this._calcFreq(),\n });\n };\n\n /**\n * Start the loop\n * @method start\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a starting time\n */\n p5.SoundLoop.prototype.start = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (!this.isPlaying) {\n this.clock.start(now + t);\n this.isPlaying = true;\n }\n };\n\n /**\n * Stop the loop\n * @method stop\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a stopping time\n */\n p5.SoundLoop.prototype.stop = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.stop(now + t);\n this.isPlaying = false;\n }\n };\n /**\n * Pause the loop\n * @method pause\n * @for p5.SoundLoop\n * @param {Number} [timeFromNow] schedule a pausing time\n */\n p5.SoundLoop.prototype.pause = function (timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n if (this.isPlaying) {\n this.clock.pause(now + t);\n this.isPlaying = false;\n }\n };\n\n /**\n * Synchronize loops. Use this method to start two or more loops in synchronization\n * or to start a loop in synchronization with a loop that is already playing\n * This method will schedule the implicit loop in sync with the explicit master loop\n * i.e. loopToStart.syncedStart(loopToSyncWith)\n *\n * @method syncedStart\n * @for p5.SoundLoop\n * @param {Object} otherLoop a p5.SoundLoop to sync with\n * @param {Number} [timeFromNow] Start the loops in sync after timeFromNow seconds\n */\n p5.SoundLoop.prototype.syncedStart = function (otherLoop, timeFromNow) {\n var t = timeFromNow || 0;\n var now = p5sound.audiocontext.currentTime;\n\n if (!otherLoop.isPlaying) {\n otherLoop.clock.start(now + t);\n otherLoop.isPlaying = true;\n this.clock.start(now + t);\n this.isPlaying = true;\n } else if (otherLoop.isPlaying) {\n var time = otherLoop.clock._nextTick - p5sound.audiocontext.currentTime;\n this.clock.start(now + time);\n this.isPlaying = true;\n }\n };\n\n /**\n * Updates frequency value, reflected in next callback\n * @private\n * @for p5.SoundLoop\n * @method _update\n */\n p5.SoundLoop.prototype._update = function () {\n this.clock.frequency.value = this._calcFreq();\n };\n\n /**\n * Calculate the frequency of the clock's callback based on bpm, interval, and timesignature\n * @private\n * @for p5.SoundLoop\n * @method _calcFreq\n * @return {Number} new clock frequency value\n */\n p5.SoundLoop.prototype._calcFreq = function () {\n //Seconds mode, bpm / timesignature has no effect\n if (typeof this._interval === 'number') {\n this.musicalTimeMode = false;\n return 1 / this._interval;\n }\n //Musical timing mode, calculate interval based bpm, interval,and time signature\n else if (typeof this._interval === 'string') {\n this.musicalTimeMode = true;\n return (\n (this._bpm / 60 / this._convertNotation(this._interval)) *\n (this._timeSignature / 4)\n );\n }\n };\n\n /**\n * Convert notation from musical time format to seconds\n * Uses Tone.Time convention\n * @private\n * @for p5.SoundLoop\n * @method _convertNotation\n * @param {String} value value to be converted\n * @return {Number} converted value in seconds\n */\n p5.SoundLoop.prototype._convertNotation = function (value) {\n var type = value.slice(-1);\n value = Number(value.slice(0, -1));\n switch (type) {\n case 'm':\n return this._measure(value);\n case 'n':\n return this._note(value);\n default:\n console.warn(\n 'Specified interval is not formatted correctly. See Tone.js ' +\n 'timing reference for more info: https://github.com/Tonejs/Tone.js/wiki/Time'\n );\n }\n };\n\n /**\n * Helper conversion methods of measure and note\n * @private\n * @for p5.SoundLoop\n * @method _measure\n */\n p5.SoundLoop.prototype._measure = function (value) {\n return value * this._timeSignature;\n };\n\n /**\n * @private\n * @method _note\n * @for p5.SoundLoop\n */\n p5.SoundLoop.prototype._note = function (value) {\n return this._timeSignature / value;\n };\n\n /**\n * Getters and Setters, setting any paramter will result in a change in the clock's\n * frequency, that will be reflected after the next callback\n * beats per minute (defaults to 60)\n * @property {Number} bpm\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'bpm', {\n get: function () {\n return this._bpm;\n },\n set: function (bpm) {\n if (!this.musicalTimeMode) {\n console.warn(\n 'Changing the BPM in \"seconds\" mode has no effect. ' +\n 'BPM is only relevant in musicalTimeMode ' +\n 'when the interval is specified as a string ' +\n '(\"2n\", \"4n\", \"1m\"...etc)'\n );\n }\n this._bpm = bpm;\n this._update();\n },\n });\n\n /**\n * number of quarter notes in a measure (defaults to 4)\n * @property {Number} timeSignature\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'timeSignature', {\n get: function () {\n return this._timeSignature;\n },\n set: function (timeSig) {\n if (!this.musicalTimeMode) {\n console.warn(\n 'Changing the timeSignature in \"seconds\" mode has no effect. ' +\n 'BPM is only relevant in musicalTimeMode ' +\n 'when the interval is specified as a string ' +\n '(\"2n\", \"4n\", \"1m\"...etc)'\n );\n }\n this._timeSignature = timeSig;\n this._update();\n },\n });\n\n /**\n * length of the loops interval\n * @property {Number|String} interval\n * @for p5.SoundLoop\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'interval', {\n get: function () {\n return this._interval;\n },\n set: function (interval) {\n this.musicalTimeMode = typeof interval === 'number' ? false : true;\n this._interval = interval;\n this._update();\n },\n });\n\n /**\n * how many times the callback has been called so far\n * @property {Number} iterations\n * @for p5.SoundLoop\n * @readonly\n */\n Object.defineProperty(p5.SoundLoop.prototype, 'iterations', {\n get: function () {\n return this.clock.ticks;\n },\n });\n\n return p5.SoundLoop;\n});\n","define(function (require) {\n 'use strict';\n\n var Effect = require('effect');\n\n /**\n * Compressor is an audio effect class that performs dynamics compression\n * on an audio input source. This is a very commonly used technique in music\n * and sound production. Compression creates an overall louder, richer,\n * and fuller sound by lowering the volume of louds and raising that of softs.\n * Compression can be used to avoid clipping (sound distortion due to\n * peaks in volume) and is especially useful when many sounds are played\n * at once. Compression can be used on indivudal sound sources in addition\n * to the master output.\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Compressor\n * @constructor\n * @extends p5.Effect\n *\n *\n */\n p5.Compressor = function () {\n Effect.call(this);\n\n /**\n * The p5.Compressor is built with a Web Audio Dynamics Compressor Node\n * \n * @property {AudioNode} compressor\n */\n\n this.compressor = this.ac.createDynamicsCompressor();\n\n this.input.connect(this.compressor);\n this.compressor.connect(this.wet);\n };\n\n p5.Compressor.prototype = Object.create(Effect.prototype);\n\n /**\n * Performs the same function as .connect, but also accepts\n * optional parameters to set compressor's audioParams\n * @method process\n * @for p5.Compressor\n *\n * @param {Object} src Sound source to be connected\n *\n * @param {Number} [attack] The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [threshold] The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [release] The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.process = function (\n src,\n attack,\n knee,\n ratio,\n threshold,\n release\n ) {\n src.connect(this.input);\n this.set(attack, knee, ratio, threshold, release);\n };\n\n /**\n * Set the paramters of a compressor.\n * @method set\n * @for p5.Compressor\n * @param {Number} attack The amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} knee A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} ratio The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n */\n p5.Compressor.prototype.set = function (\n attack,\n knee,\n ratio,\n threshold,\n release\n ) {\n if (typeof attack !== 'undefined') {\n this.attack(attack);\n }\n if (typeof knee !== 'undefined') {\n this.knee(knee);\n }\n if (typeof ratio !== 'undefined') {\n this.ratio(ratio);\n }\n if (typeof threshold !== 'undefined') {\n this.threshold(threshold);\n }\n if (typeof release !== 'undefined') {\n this.release(release);\n }\n };\n\n /**\n * Get current attack or set value w/ time ramp\n *\n *\n * @method attack\n * @for p5.Compressor\n * @param {Number} [attack] Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n * default = .003, range 0 - 1\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.attack = function (attack, time) {\n var t = time || 0;\n if (typeof attack === 'number') {\n this.compressor.attack.value = attack;\n this.compressor.attack.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.attack.linearRampToValueAtTime(\n attack,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof attack !== 'undefined') {\n attack.connect(this.compressor.attack);\n }\n return this.compressor.attack.value;\n };\n\n /**\n * Get current knee or set value w/ time ramp\n *\n * @method knee\n * @for p5.Compressor\n * @param {Number} [knee] A decibel value representing the range above the\n * threshold where the curve smoothly transitions to the \"ratio\" portion.\n * default = 30, range 0 - 40\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.knee = function (knee, time) {\n var t = time || 0;\n if (typeof knee === 'number') {\n this.compressor.knee.value = knee;\n this.compressor.knee.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.knee.linearRampToValueAtTime(\n knee,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof knee !== 'undefined') {\n knee.connect(this.compressor.knee);\n }\n return this.compressor.knee.value;\n };\n\n /**\n * Get current ratio or set value w/ time ramp\n * @method ratio\n * @for p5.Compressor\n * @param {Number} [ratio] The amount of dB change in input for a 1 dB change in output\n * default = 12, range 1 - 20\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.ratio = function (ratio, time) {\n var t = time || 0;\n if (typeof ratio === 'number') {\n this.compressor.ratio.value = ratio;\n this.compressor.ratio.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.ratio.linearRampToValueAtTime(\n ratio,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof ratio !== 'undefined') {\n ratio.connect(this.compressor.ratio);\n }\n return this.compressor.ratio.value;\n };\n\n /**\n * Get current threshold or set value w/ time ramp\n * @method threshold\n * @for p5.Compressor\n * @param {Number} threshold The decibel value above which the compression will start taking effect\n * default = -24, range -100 - 0\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.threshold = function (threshold, time) {\n var t = time || 0;\n if (typeof threshold === 'number') {\n this.compressor.threshold.value = threshold;\n this.compressor.threshold.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.threshold.linearRampToValueAtTime(\n threshold,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof threshold !== 'undefined') {\n threshold.connect(this.compressor.threshold);\n }\n return this.compressor.threshold.value;\n };\n\n /**\n * Get current release or set value w/ time ramp\n * @method release\n * @for p5.Compressor\n * @param {Number} release The amount of time (in seconds) to increase the gain by 10dB\n * default = .25, range 0 - 1\n *\n * @param {Number} [time] Assign time value to schedule the change in value\n */\n p5.Compressor.prototype.release = function (release, time) {\n var t = time || 0;\n if (typeof release === 'number') {\n this.compressor.release.value = release;\n this.compressor.release.cancelScheduledValues(\n this.ac.currentTime + 0.01 + t\n );\n this.compressor.release.linearRampToValueAtTime(\n release,\n this.ac.currentTime + 0.02 + t\n );\n } else if (typeof number !== 'undefined') {\n release.connect(this.compressor.release);\n }\n return this.compressor.release.value;\n };\n\n /**\n * Return the current reduction value\n *\n * @method reduction\n * @for p5.Compressor\n * @return {Number} Value of the amount of gain reduction that is applied to the signal\n */\n p5.Compressor.prototype.reduction = function () {\n return this.compressor.reduction.value;\n };\n\n p5.Compressor.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.compressor) {\n this.compressor.disconnect();\n delete this.compressor;\n }\n };\n\n return p5.Compressor;\n});\n","'use strict';\n\ndefine(function (require) {\n // inspiration: recorder.js, Tone.js & typedarray.org\n\n const p5sound = require('master');\n const { convertToWav, safeBufferSize } = require('helpers');\n const processorNames = require('./audioWorklet/processorNames');\n const ac = p5sound.audiocontext;\n\n /**\n *

Record sounds for playback and/or to save as a .wav file.\n * The p5.SoundRecorder records all sound output from your sketch,\n * or can be assigned a specific source with setInput().

\n *

The record() method accepts a p5.SoundFile as a parameter.\n * When playback is stopped (either after the given amount of time,\n * or with the stop() method), the p5.SoundRecorder will send its\n * recording to that p5.SoundFile for playback.

\n *\n * @class p5.SoundRecorder\n * @constructor\n * @example\n *
\n * let mic, recorder, soundFile;\n * let state = 0;\n *\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(canvasPressed);\n * background(220);\n * textAlign(CENTER, CENTER);\n *\n * // create an audio in\n * mic = new p5.AudioIn();\n *\n * // prompts user to enable their browser mic\n * mic.start();\n *\n * // create a sound recorder\n * recorder = new p5.SoundRecorder();\n *\n * // connect the mic to the recorder\n * recorder.setInput(mic);\n *\n * // this sound file will be used to\n * // playback & save the recording\n * soundFile = new p5.SoundFile();\n *\n * text('tap to record', width/2, height/2);\n * }\n *\n * function canvasPressed() {\n * // ensure audio is enabled\n * userStartAudio();\n *\n * // make sure user enabled the mic\n * if (state === 0 && mic.enabled) {\n *\n * // record to our p5.SoundFile\n * recorder.record(soundFile);\n *\n * background(255,0,0);\n * text('Recording!', width/2, height/2);\n * state++;\n * }\n * else if (state === 1) {\n * background(0,255,0);\n *\n * // stop recorder and\n * // send result to soundFile\n * recorder.stop();\n *\n * text('Done! Tap to play and download', width/2, height/2, width - 20);\n * state++;\n * }\n *\n * else if (state === 2) {\n * soundFile.play(); // play the result!\n * save(soundFile, 'mySound.wav');\n * state++;\n * }\n * }\n *
\n */\n p5.SoundRecorder = function () {\n this.input = ac.createGain();\n this.output = ac.createGain();\n\n this._inputChannels = 2;\n this._outputChannels = 2; // stereo output, even if input is mono\n\n const workletBufferSize = safeBufferSize(1024);\n\n this._workletNode = new AudioWorkletNode(\n ac,\n processorNames.recorderProcessor,\n {\n outputChannelCount: [this._outputChannels],\n processorOptions: {\n numInputChannels: this._inputChannels,\n bufferSize: workletBufferSize,\n },\n }\n );\n\n this._workletNode.port.onmessage = function (event) {\n if (event.data.name === 'buffers') {\n const buffers = [\n new Float32Array(event.data.leftBuffer),\n new Float32Array(event.data.rightBuffer),\n ];\n this._callback(buffers);\n }\n }.bind(this);\n\n /**\n * callback invoked when the recording is over\n * @private\n * @type Function(Float32Array)\n */\n this._callback = function () {};\n\n // connections\n this._workletNode.connect(p5.soundOut._silentNode);\n this.setInput();\n\n // add this p5.SoundFile to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a specific device to the p5.SoundRecorder.\n * If no parameter is given, p5.SoundRecorer will record\n * all audible p5.sound from your sketch.\n *\n * @method setInput\n * @for p5.SoundRecorder\n * @param {Object} [unit] p5.sound object or a web audio unit\n * that outputs sound\n */\n p5.SoundRecorder.prototype.setInput = function (unit) {\n this.input.disconnect();\n this.input = null;\n this.input = ac.createGain();\n this.input.connect(this._workletNode);\n this.input.connect(this.output);\n if (unit) {\n unit.connect(this.input);\n } else {\n p5.soundOut.output.connect(this.input);\n }\n };\n\n /**\n * Start recording. To access the recording, provide\n * a p5.SoundFile as the first parameter. The p5.SoundRecorder\n * will send its recording to that p5.SoundFile for playback once\n * recording is complete. Optional parameters include duration\n * (in seconds) of the recording, and a callback function that\n * will be called once the complete recording has been\n * transfered to the p5.SoundFile.\n *\n * @method record\n * @for p5.SoundRecorder\n * @param {p5.SoundFile} soundFile p5.SoundFile\n * @param {Number} [duration] Time (in seconds)\n * @param {Function} [callback] The name of a function that will be\n * called once the recording completes\n */\n p5.SoundRecorder.prototype.record = function (sFile, duration, callback) {\n this._workletNode.port.postMessage({ name: 'start', duration: duration });\n\n if (sFile && callback) {\n this._callback = function (buffer) {\n sFile.setBuffer(buffer);\n callback();\n };\n } else if (sFile) {\n this._callback = function (buffer) {\n sFile.setBuffer(buffer);\n };\n }\n };\n\n /**\n * Stop the recording. Once the recording is stopped,\n * the results will be sent to the p5.SoundFile that\n * was given on .record(), and if a callback function\n * was provided on record, that function will be called.\n *\n * @method stop\n * @for p5.SoundRecorder\n */\n p5.SoundRecorder.prototype.stop = function () {\n this._workletNode.port.postMessage({ name: 'stop' });\n };\n\n p5.SoundRecorder.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n\n this._callback = function () {};\n if (this.input) {\n this.input.disconnect();\n }\n this.input = null;\n this._workletNode = null;\n };\n\n /**\n * Save a p5.SoundFile as a .wav file. The browser will prompt the user\n * to download the file to their device.\n * For uploading audio to a server, use\n * `p5.SoundFile.saveBlob`.\n *\n * @for p5\n * @method saveSound\n * @param {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n * @param {String} fileName name of the resulting .wav file.\n */\n // add to p5.prototype as this is used by the p5 `save()` method.\n p5.prototype.saveSound = function (soundFile, fileName) {\n const dataView = convertToWav(soundFile.buffer);\n p5.prototype.writeFile([dataView], fileName, 'wav');\n };\n});\n","'use strict';\n\ndefine(function () {\n /**\n *

PeakDetect works in conjunction with p5.FFT to\n * look for onsets in some or all of the frequency spectrum.\n *

\n *

\n * To use p5.PeakDetect, call update in the draw loop\n * and pass in a p5.FFT object.\n *

\n *

\n * You can listen for a specific part of the frequency spectrum by\n * setting the range between freq1 and freq2.\n *

\n *\n *

threshold is the threshold for detecting a peak,\n * scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\n * as 1.0.

\n *\n *

\n * The update method is meant to be run in the draw loop, and\n * frames determines how many loops must pass before\n * another peak can be detected.\n * For example, if the frameRate() = 60, you could detect the beat of a\n * 120 beat-per-minute song with this equation:\n * framesPerPeak = 60 / (estimatedBPM / 60 );\n *

\n *\n *

\n * Based on example contribtued by @b2renger, and a simple beat detection\n * explanation by Felix Turner.\n *

\n *\n * @class p5.PeakDetect\n * @constructor\n * @param {Number} [freq1] lowFrequency - defaults to 20Hz\n * @param {Number} [freq2] highFrequency - defaults to 20000 Hz\n * @param {Number} [threshold] Threshold for detecting a beat between 0 and 1\n * scaled logarithmically where 0.1 is 1/2 the loudness\n * of 1.0. Defaults to 0.35.\n * @param {Number} [framesPerPeak] Defaults to 20.\n * @example\n *
\n *\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 10;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * background(0);\n * noStroke();\n * fill(255);\n * textAlign(CENTER);\n *\n * // p5.PeakDetect requires a p5.FFT\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n * }\n *\n * function draw() {\n * background(0);\n * text('click to play/pause', width/2, height/2);\n *\n * // peakDetect accepts an fft post-analysis\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * if ( peakDetect.isDetected ) {\n * ellipseWidth = 50;\n * } else {\n * ellipseWidth *= 0.95;\n * }\n *\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // toggle play/stop when canvas is clicked\n * function mouseClicked() {\n * if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * }\n * }\n *
\n */\n p5.PeakDetect = function (freq1, freq2, threshold, _framesPerPeak) {\n // framesPerPeak determines how often to look for a beat.\n // If a beat is provided, try to look for a beat based on bpm\n this.framesPerPeak = _framesPerPeak || 20;\n this.framesSinceLastPeak = 0;\n this.decayRate = 0.95;\n\n this.threshold = threshold || 0.35;\n this.cutoff = 0;\n\n // how much to increase the cutoff\n // TO DO: document this / figure out how to make it accessible\n this.cutoffMult = 1.5;\n\n this.energy = 0;\n this.penergy = 0;\n\n // TO DO: document this property / figure out how to make it accessible\n this.currentValue = 0;\n\n /**\n * isDetected is set to true when a peak is detected.\n *\n * @attribute isDetected {Boolean}\n * @default false\n */\n this.isDetected = false;\n\n this.f1 = freq1 || 40;\n this.f2 = freq2 || 20000;\n\n // function to call when a peak is detected\n this._onPeak = function () {};\n };\n\n /**\n * The update method is run in the draw loop.\n *\n * Accepts an FFT object. You must call .analyze()\n * on the FFT object prior to updating the peakDetect\n * because it relies on a completed FFT analysis.\n *\n * @method update\n * @param {p5.FFT} fftObject A p5.FFT object\n */\n p5.PeakDetect.prototype.update = function (fftObject) {\n var nrg = (this.energy = fftObject.getEnergy(this.f1, this.f2) / 255);\n if (nrg > this.cutoff && nrg > this.threshold && nrg - this.penergy > 0) {\n // trigger callback\n this._onPeak();\n this.isDetected = true;\n\n // debounce\n this.cutoff = nrg * this.cutoffMult;\n this.framesSinceLastPeak = 0;\n } else {\n this.isDetected = false;\n if (this.framesSinceLastPeak <= this.framesPerPeak) {\n this.framesSinceLastPeak++;\n } else {\n this.cutoff *= this.decayRate;\n this.cutoff = Math.max(this.cutoff, this.threshold);\n }\n }\n\n this.currentValue = nrg;\n this.penergy = nrg;\n };\n\n /**\n * onPeak accepts two arguments: a function to call when\n * a peak is detected. The value of the peak,\n * between 0.0 and 1.0, is passed to the callback.\n *\n * @method onPeak\n * @param {Function} callback Name of a function that will\n * be called when a peak is\n * detected.\n * @param {Object} [val] Optional value to pass\n * into the function when\n * a peak is detected.\n * @example\n *
\n * var cnv, soundFile, fft, peakDetect;\n * var ellipseWidth = 0;\n *\n * function preload() {\n * soundFile = loadSound('assets/beat.mp3');\n * }\n *\n * function setup() {\n * cnv = createCanvas(100,100);\n * textAlign(CENTER);\n *\n * fft = new p5.FFT();\n * peakDetect = new p5.PeakDetect();\n *\n * setupSound();\n *\n * // when a beat is detected, call triggerBeat()\n * peakDetect.onPeak(triggerBeat);\n * }\n *\n * function draw() {\n * background(0);\n * fill(255);\n * text('click to play', width/2, height/2);\n *\n * fft.analyze();\n * peakDetect.update(fft);\n *\n * ellipseWidth *= 0.95;\n * ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n * }\n *\n * // this function is called by peakDetect.onPeak\n * function triggerBeat() {\n * ellipseWidth = 50;\n * }\n *\n * // mouseclick starts/stops sound\n * function setupSound() {\n * cnv.mouseClicked( function() {\n * if (soundFile.isPlaying() ) {\n * soundFile.stop();\n * } else {\n * soundFile.play();\n * }\n * });\n * }\n *
\n */\n p5.PeakDetect.prototype.onPeak = function (callback, val) {\n var self = this;\n\n self._onPeak = function () {\n callback(self.energy, val);\n };\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var p5sound = require('master');\n\n /**\n * A gain node is usefull to set the relative volume of sound.\n * It's typically used to build mixers.\n *\n * @class p5.Gain\n * @constructor\n * @example\n *
\n *\n * // load two soundfile and crossfade beetween them\n * let sound1,sound2;\n * let sound1Gain, sound2Gain, masterGain;\n * function preload(){\n * soundFormats('ogg', 'mp3');\n * sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n * sound2 = loadSound('assets/beat');\n * }\n * function setup() {\n * let cnv = createCanvas(100, 100);\n * cnv.mousePressed(startSound);\n * // create a 'master' gain to which we will connect both soundfiles\n * masterGain = new p5.Gain();\n * masterGain.connect();\n * sound1.disconnect(); // diconnect from p5 output\n * sound1Gain = new p5.Gain(); // setup a gain node\n * sound1Gain.setInput(sound1); // connect the first sound to its input\n * sound1Gain.connect(masterGain); // connect its output to the 'master'\n * sound2.disconnect();\n * sound2Gain = new p5.Gain();\n * sound2Gain.setInput(sound2);\n * sound2Gain.connect(masterGain);\n * }\n * function startSound() {\n * sound1.loop();\n * sound2.loop();\n * loop();\n * }\n * function mouseReleased() {\n * sound1.stop();\n * sound2.stop();\n * }\n * function draw(){\n * background(220);\n * textAlign(CENTER);\n * textSize(11);\n * fill(0);\n * if (!sound1.isPlaying()) {\n * text('tap and drag to play', width/2, height/2);\n * return;\n * }\n * // map the horizontal position of the mouse to values useable for volume * control of sound1\n * var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n * var sound2Volume = 1-sound1Volume;\n * sound1Gain.amp(sound1Volume);\n * sound2Gain.amp(sound2Volume);\n * // map the vertical position of the mouse to values useable for 'master * volume control'\n * var masterVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n * masterGain.amp(masterVolume);\n * text('master', width/2, height - masterVolume * height * 0.9)\n * fill(255, 0, 255);\n * textAlign(LEFT);\n * text('sound1', 5, height - sound1Volume * height * 0.9);\n * textAlign(RIGHT);\n * text('sound2', width - 5, height - sound2Volume * height * 0.9);\n * }\n *
\n */\n\n p5.Gain = function () {\n this.ac = p5sound.audiocontext;\n\n this.input = this.ac.createGain();\n this.output = this.ac.createGain();\n\n // otherwise, Safari distorts\n this.input.gain.value = 0.5;\n this.input.connect(this.output);\n\n // add to the soundArray\n p5sound.soundArray.push(this);\n };\n\n /**\n * Connect a source to the gain node.\n *\n * @method setInput\n * @for p5.Gain\n * @param {Object} src p5.sound / Web Audio object with a sound\n * output.\n */\n\n p5.Gain.prototype.setInput = function (src) {\n src.connect(this.input);\n };\n\n /**\n * Send output to a p5.sound or web audio object\n *\n * @method connect\n * @for p5.Gain\n * @param {Object} unit\n */\n p5.Gain.prototype.connect = function (unit) {\n var u = unit || p5.soundOut.input;\n this.output.connect(u.input ? u.input : u);\n };\n\n /**\n * Disconnect all output.\n *\n * @method disconnect\n * @for p5.Gain\n */\n p5.Gain.prototype.disconnect = function () {\n if (this.output) {\n this.output.disconnect();\n }\n };\n\n /**\n * Set the output level of the gain node.\n *\n * @method amp\n * @for p5.Gain\n * @param {Number} volume amplitude between 0 and 1.0\n * @param {Number} [rampTime] create a fade that lasts rampTime\n * @param {Number} [timeFromNow] schedule this event to happen\n * seconds from now\n */\n p5.Gain.prototype.amp = function (vol, rampTime = 0, tFromNow = 0) {\n var now = p5sound.audiocontext.currentTime;\n var currentVol = this.output.gain.value;\n this.output.gain.cancelScheduledValues(now);\n this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n };\n\n p5.Gain.prototype.dispose = function () {\n // remove reference from soundArray\n var index = p5sound.soundArray.indexOf(this);\n p5sound.soundArray.splice(index, 1);\n if (this.output) {\n this.output.disconnect();\n delete this.output;\n }\n if (this.input) {\n this.input.disconnect();\n delete this.input;\n }\n };\n});\n","'use strict';\n\ndefine(function (require) {\n var Effect = require('effect');\n\n /*\n * Adapted from [Kevin Ennis on StackOverflow](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n */\n function makeDistortionCurve(amount) {\n var k = typeof amount === 'number' ? amount : 50;\n var numSamples = 44100;\n var curve = new Float32Array(numSamples);\n var deg = Math.PI / 180;\n var i = 0;\n var x;\n for (; i < numSamples; ++i) {\n x = (i * 2) / numSamples - 1;\n curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));\n }\n return curve;\n }\n\n /**\n * A Distortion effect created with a Waveshaper Node,\n * with an approach adapted from\n * [Kevin Ennis](http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion)\n *\n * This class extends p5.Effect.\n * Methods amp(), chain(),\n * drywet(), connect(), and\n * disconnect() are available.\n *\n * @class p5.Distortion\n * @extends p5.Effect\n * @constructor\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n *\n */\n p5.Distortion = function (amount, oversample) {\n Effect.call(this);\n\n if (typeof amount === 'undefined') {\n amount = 0.25;\n }\n if (typeof amount !== 'number') {\n throw new Error('amount must be a number');\n }\n if (typeof oversample === 'undefined') {\n oversample = '2x';\n }\n if (typeof oversample !== 'string') {\n throw new Error('oversample must be a String');\n }\n\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n\n /**\n * The p5.Distortion is built with a\n * \n * Web Audio WaveShaper Node.\n *\n * @property {AudioNode} WaveShaperNode\n */\n this.waveShaperNode = this.ac.createWaveShaper();\n\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n this.waveShaperNode.oversample = oversample;\n\n this.input.connect(this.waveShaperNode);\n\n this.waveShaperNode.connect(this.wet);\n };\n\n p5.Distortion.prototype = Object.create(Effect.prototype);\n\n /**\n * Process a sound source, optionally specify amount and oversample values.\n *\n * @method process\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.process = function (src, amount, oversample) {\n src.connect(this.input);\n this.set(amount, oversample);\n };\n\n /**\n * Set the amount and oversample of the waveshaper distortion.\n *\n * @method set\n * @for p5.Distortion\n * @param {Number} [amount=0.25] Unbounded distortion amount.\n * Normal values range from 0-1.\n * @param {String} [oversample='none'] 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.set = function (amount, oversample) {\n if (amount) {\n var curveAmount = p5.prototype.map(amount, 0.0, 1.0, 0, 2000);\n this.amount = curveAmount;\n this.waveShaperNode.curve = makeDistortionCurve(curveAmount);\n }\n if (oversample) {\n this.waveShaperNode.oversample = oversample;\n }\n };\n\n /**\n * Return the distortion amount, typically between 0-1.\n *\n * @method getAmount\n * @for p5.Distortion\n * @return {Number} Unbounded distortion amount.\n * Normal values range from 0-1.\n */\n p5.Distortion.prototype.getAmount = function () {\n return this.amount;\n };\n\n /**\n * Return the oversampling.\n *\n * @method getOversample\n * @for p5.Distortion\n * @return {String} Oversample can either be 'none', '2x', or '4x'.\n */\n p5.Distortion.prototype.getOversample = function () {\n return this.waveShaperNode.oversample;\n };\n\n p5.Distortion.prototype.dispose = function () {\n Effect.prototype.dispose.apply(this);\n if (this.waveShaperNode) {\n this.waveShaperNode.disconnect();\n this.waveShaperNode = null;\n }\n };\n});\n"],"sourceRoot":""} \ No newline at end of file From 2c0c9f093d845502da1c32e87d06b9347cec3781 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Sun, 24 May 2020 12:09:39 +0200 Subject: [PATCH 9/9] Update links to the GitHub repository --- README.md | 2 +- fragments/before.frag | 4 ++-- todo.md | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 313717ec..cd5bc96e 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Interactive documentation at [p5js.org/reference/#/libraries/p5.sound](http://p5 ### Latest Build * Visit http://p5js.org/download/ for the latest official release of p5 with the latest p5.sound included. -* The sound library [here](https://github.com/therewasaguy/p5.sound/blob/master/lib) is updated more frequently, and we occasionally offer new [releases](https://github.com/processing/p5.js-sound/releases) before p5's release cycle. +* The sound library [here](https://github.com/processing/p5.js-sound/blob/master/lib) is updated more frequently, and we occasionally offer new [releases](https://github.com/processing/p5.js-sound/releases) before p5's release cycle. ### Contribute diff --git a/fragments/before.frag b/fragments/before.frag index e85faada..de0f008e 100644 --- a/fragments/before.frag +++ b/fragments/before.frag @@ -38,9 +38,9 @@ * *
  • userStartAudio: Enable audio in a * browser- and user-friendly way. - *

    p5.sound is on GitHub. + *

    p5.sound is on GitHub. * Download the latest version - * here.

    + * here.

    * * @module p5.sound * @submodule p5.sound diff --git a/todo.md b/todo.md index aa96a3e5..22e69be0 100644 --- a/todo.md +++ b/todo.md @@ -19,14 +19,14 @@ p5.sound to do list - Log a message to the console if a user calls FFT methods like getEnergy without first calling .analyze() in either the draw loop, or in the method in which they call getEnergy. Maybe log the time that .analyze was last called, and compare it to the current time, and if it is a big gap, then log the message? -- SoundFile.playMode('untilDone') would play a sound if not already playing, but if it is already playing, it would not play again until it is done. Feel free to re-open this [Github Issue](https://github.com/therewasaguy/p5.sound/issues/5) if you want to work on this. +- SoundFile.playMode('untilDone') would play a sound if not already playing, but if it is already playing, it would not play again until it is done. Feel free to re-open this [Github Issue](https://github.com/processing/p5.js-sound/issues/5) if you want to work on this. - Improve p5.Pulse (PWM) - What additional features/analysis would be useful for visualization / analysis? Look into handling these with an offline audio context, and/or scripts that could analyze a file and then save the result to JSON. - * Peak Detect https://github.com/therewasaguy/p5.sound/issues/12 + * Peak Detect https://github.com/processing/p5.js-sound/issues/12 * Beat Detect -- [here's an example](http://tech.beatport.com/2014/web-audio/beat-detection-using-web-audio/) handled by an offline audio context * Pitch detect -- [here's an example](https://webaudiodemos.appspot.com/pitchdetect/index.html). @@ -78,7 +78,7 @@ p5.sound to do list - p5.Envelope takes no action on triggerRelease unless currently playing - Add a logarithmic scaling option for p5.FFT -- p5.SoundFile.getPeaks should be able to return stereo peaks. Like [this](https://github.com/olosmusic/olos-soundfile/blob/master/olos-soundfile.html#L379) +- p5.SoundFile.getPeaks should be able to return stereo peaks. Like [this](https://github.com/olosmusic/olos-soundfile/blob/master/olos-soundfile.html#L379) - Add the ability to decode audio buffer data from a FileReader and add it to a p5.SoundFile buffer, like [this](https://github.com/olosmusic/olos-soundfile/blob/master/olos-soundfile.html#L227) - Add ability to map a soundfile playback rate to a pitch ratio, like [this](https://github.com/ericrosenbaum/MK-1/blob/gh-pages/sketch.js#L488) - when a soundFile is reversed, reverse currentTime as well for accurate playback position