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');