xsound 2.26.4 → 2.26.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"xsound.js","mappings":"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","sources":["webpack://xsound/./src/interfaces/Connectable.js","webpack://xsound/./src/SoundModule/Analyser/Visualizer.js","webpack://xsound/./src/SoundModule/Analyser/TimeOverview.js","webpack://xsound/./src/SoundModule/Analyser/Time.js","webpack://xsound/./src/SoundModule/Analyser/FFT.js","webpack://xsound/./src/SoundModule/Analyser/index.js","webpack://xsound/./src/SoundModule/Recorder/Track.js","webpack://xsound/./src/SoundModule/Recorder/Channel.js","webpack://xsound/./src/SoundModule/Recorder/index.js","webpack://xsound/./src/SoundModule/Session.js","webpack://xsound/./src/SoundModule/Effectors/Effector.js","webpack://xsound/./src/SoundModule/Effectors/Autopanner.js","webpack://xsound/./src/SoundModule/Effectors/AutopannerFallback.js","webpack://xsound/./src/SoundModule/Effectors/Chorus.js","webpack://xsound/./src/SoundModule/Effectors/Compressor.js","webpack://xsound/./src/SoundModule/Effectors/Delay.js","webpack://xsound/./src/SoundModule/Effectors/Distortion.js","webpack://xsound/./src/SoundModule/Effectors/EnvelopeGenerator.js","webpack://xsound/./src/SoundModule/Effectors/Equalizer.js","webpack://xsound/./src/SoundModule/Effectors/Filter.js","webpack://xsound/./src/SoundModule/Effectors/Flanger.js","webpack://xsound/./src/SoundModule/Effectors/Listener.js","webpack://xsound/./src/SoundModule/Effectors/Panner.js","webpack://xsound/./src/SoundModule/Effectors/Phaser.js","webpack://xsound/./src/SoundModule/Effectors/PitchShifter.js","webpack://xsound/./src/SoundModule/Effectors/Reverb.js","webpack://xsound/./src/SoundModule/Effectors/Ringmodulator.js","webpack://xsound/./src/SoundModule/Effectors/Stereo.js","webpack://xsound/./src/SoundModule/Effectors/Tremolo.js","webpack://xsound/./src/SoundModule/Effectors/Wah.js","webpack://xsound/./src/SoundModule/index.js","webpack://xsound/./src/OscillatorModule/Oscillator.js","webpack://xsound/./src/OscillatorModule/Glide.js","webpack://xsound/./src/OscillatorModule/index.js","webpack://xsound/./src/OneshotModule/index.js","webpack://xsound/./src/NoiseModule/index.js","webpack://xsound/./src/AudioModule/VocalCanceler.js","webpack://xsound/./src/AudioModule/index.js","webpack://xsound/./src/MediaModule/index.js","webpack://xsound/./src/StreamModule/NoiseGate.js","webpack://xsound/./src/StreamModule/NoiseSuppressor.js","webpack://xsound/./src/StreamModule/index.js","webpack://xsound/./src/MixerModule/index.js","webpack://xsound/./src/ProcessorModule/index.js","webpack://xsound/./src/MIDI/index.js","webpack://xsound/./src/MML/Token.js","webpack://xsound/./src/MML/Tokenizer.js","webpack://xsound/./src/MML/Tree.js","webpack://xsound/./src/MML/TreeConstructor.js","webpack://xsound/./src/MML/Sequence.js","webpack://xsound/./src/MML/Sequencer.js","webpack://xsound/./src/MML/Part.js","webpack://xsound/./src/MML/index.js","webpack://xsound/./src/XSound/index.js","webpack://xsound/./src/main.js"],"sourcesContent":["'use strict';\n\n/**\n * This interface defines behaviors for connection to `AudioNode`.\n * @interface\n */\nexport class Connectable {\n /**\n * for input\n */\n INPUT() {}\n\n /**\n * for output\n */\n OUTPUT() {}\n}\n","'use strict';\n\n/**\n * This private class defines the properties that subclasses (`TimeOverview`, `Time`, `FFT`) require.\n * @constructor\n */\nexport class Visualizer {\n static CANVAS = 'canvas';\n static SVG = 'svg';\n\n static XMLNS = 'http://www.w3.org/2000/svg';\n static XLINK = 'http://www.w3.org/1999/xlink';\n\n static SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW = 'svg-linear-gradient-time-overview';\n static SVG_LINEAR_GRADIENT_ID_TIME = 'svg-linear-gradient-time';\n static SVG_LINEAR_GRADIENT_ID_FFT = 'svg-linear-gradient-fft';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n this.sampleRate = sampleRate;\n\n this.isActive = false;\n\n // either 'canvas' or 'svg'\n this.graphics = '';\n\n // in the case of using Canvas\n this.canvas = null;\n this.context = null;\n\n // in the case of using SVG\n this.svg = null;\n\n // for timer\n this.interval = 1000;\n this.timerid = null;\n\n this.styles = {\n 'shape' : 'line',\n 'grad' : [\n {\n 'offset' : 0,\n 'color' : 'rgba(0, 128, 255, 1.0)'\n },\n {\n 'offset' : 1,\n 'color' : 'rgba(0, 0, 255, 1.0)'\n }\n ],\n 'wave' : 'rgba(0, 0, 255, 1.0)',\n 'grid' : 'rgba(255, 0, 0, 1.0)',\n 'text' : 'rgba(255, 255, 255, 1.0)',\n 'font' : {\n 'family' : 'Arial',\n 'size' : '13px',\n 'style' : 'normal'\n },\n 'width' : 1.5,\n 'cap' : 'round',\n 'join' : 'miter',\n 'top' : 15,\n 'right' : 30,\n 'bottom' : 15,\n 'left' : 30\n };\n }\n\n /**\n * This method sets up for using Canvas or SVG.\n * @param {HTMLCanvasElement|SVGElement} element This argument is either `HTMLCanvasElement` or `SVGElement`.\n * @return {Visualizer} This is returned for method chain.\n */\n setup(element) {\n if (element instanceof HTMLCanvasElement) {\n this.graphics = Visualizer.CANVAS;\n this.canvas = element;\n this.context = this.canvas.getContext('2d');\n } else if (element instanceof SVGElement) {\n this.graphics = Visualizer.SVG;\n this.svg = element;\n\n // this.svg.setAttribute('xmlns', Visualizer.XMLNS);\n // this.svg.setAttribute('xmlns:xlink', Visualizer.XLINK);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {string|number|Array.<object>} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {string|number|Array.<object>} This is returned as the value of designated property in the case of getter.\n */\n param(key, value) {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'interval':\n if (value === undefined) {\n return this.interval;\n }\n\n if (String(value).toLowerCase() === 'auto') {\n this.interval = 'auto';\n } else {\n v = parseFloat(value);\n\n if (v >= 0) {\n this.interval = v;\n }\n }\n\n break;\n case 'shape':\n if (value === undefined) {\n return this.styles.shape;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === 'line') || (v === 'rect')) {\n this.styles.shape = (this.styles.wave !== 'gradient') ? v : 'rect';\n }\n\n break;\n case 'grad':\n if (value === undefined) {\n return this.styles.grad;\n }\n\n if (!Array.isArray(value)) {\n value = [value];\n }\n\n let isError = false;\n\n for (const grads of value) {\n if (('offset' in grads) && ('color' in grads)) {\n const offset = parseFloat(grads.offset);\n\n if (isNaN(offset) || (offset < 0) || (offset > 1)) {\n isError = true;\n break;\n }\n } else {\n isError = true;\n break;\n }\n }\n\n if (!isError) {\n this.styles.grad = value;\n }\n\n break;\n case 'font':\n if (value === undefined) {\n return this.styles[k];\n }\n\n if (Object.prototype.toString.call(value) === '[object Object]') {\n for (const prop in value) {\n if (/(?:family|size|style)/i.test(prop)) {\n this.styles.font[prop] = String(value[prop]);\n }\n }\n }\n\n break;\n case 'wave':\n case 'grid':\n case 'text':\n case 'cap' :\n case 'join':\n if (value === undefined) {\n return this.styles[k];\n }\n\n if (typeof value === 'string') {\n if ((k === 'wave') && (value === 'gradient')) {\n this.styles.shape = 'rect';\n }\n\n this.styles[k] = value.toLowerCase();\n }\n\n break;\n case 'width' :\n case 'top' :\n case 'right' :\n case 'bottom':\n case 'left' :\n if (value === undefined) {\n return this.styles[k];\n }\n\n v = (k === 'width') ? parseFloat(value) : parseInt(value, 10);\n\n if (v >= 0) {\n this.styles[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n /**\n * This method draws sound wave to Canvas or SVG. This method conceals difference of API for drawing.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is parameter for spectrum. The default value is -100 dB.\n * @param {number} maxDecibels This argument is parameter for spectrum. The default value is -30 dB.\n * @return {Visualizer} This is returned for method chain.\n */\n start(data, minDecibels, maxDecibels) {\n switch (this.graphics) {\n case Visualizer.CANVAS:\n this.drawOnCanvas(data, minDecibels, maxDecibels);\n break;\n case Visualizer.SVG:\n this.drawBySVG(data, minDecibels, maxDecibels);\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method creates string for `Data URL` or `HTML` for the drawn figure.\n * @return {string|Visualizer} This is returned as `Data URL` or `HTML` string. If `setup` method has not been invoked, this is returned for method chain.\n */\n create() {\n switch (this.graphics) {\n case Visualizer.CANVAS:\n return this.canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');\n case Visualizer.SVG:\n return this.svg.outerHTML;\n default:\n return this;\n }\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Visualizer} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n return this;\n }\n\n /**\n * This method draws time domain data of `Float32Array` to Canvas.\n * @param {CanvasRenderingContext2D} context This argument is the instance of `CanvasRenderingContext2D`.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is the width of drawing area.\n * @param {number} innerHeight This argument is the height of drawing area.\n * @param {number} middle This argument is the middle of drawing area.\n * @param {number} nPlotInterval This argument is the interval of drawing.\n */\n drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, nPlotInterval) {\n if (!(context instanceof CanvasRenderingContext2D)) {\n return this;\n }\n\n if (!(data instanceof Float32Array)) {\n return this;\n }\n\n let w = parseInt(innerWidth, 10);\n let h = parseInt(innerHeight, 10);\n let m = parseInt(middle, 10);\n\n if (isNaN(w)) { w = 0; }\n if (isNaN(h)) { h = 0; }\n if (isNaN(m)) { m = 0; }\n\n // Begin drawing\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = ((1 - data[i]) * (h / 2)) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = -1 * (data[i] * (h / 2));\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = (innerHeight / 2) + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, m, this.styles.width, y);\n }\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method draws time domain data of `Float32Array` to SVG.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is the width of drawing area.\n * @param {number} innerHeight This argument is the height of drawing area.\n * @param {number} middle This argument is the middle of drawing area.\n * @param {number} nPlotInterval This argument is the interval of drawing.\n * @param {string} linearGradientId This argument is id attribute for `SVGLinearGradientElement`.\n * @return {SVGPathElement|SVGGElement} This is returned as `SVGElement`.\n */\n drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, nPlotInterval, linearGradientId) {\n let w = parseInt(innerWidth, 10);\n let h = parseInt(innerHeight, 10);\n let m = parseInt(middle, 10);\n\n if (isNaN(w)) { w = 0; }\n if (isNaN(h)) { h = 0; }\n if (isNaN(m)) { m = 0; }\n\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = ((1 - data[i]) * (h / 2)) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n return path;\n case 'rect':\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(linearGradientId);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((i / len) * w) + this.styles.left;\n const y = data[i] * (innerHeight / 2);\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', m);\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${m})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${linearGradientId})`);\n\n g.appendChild(rect);\n }\n }\n\n return g;\n default:\n return null;\n }\n }\n\n /**\n * This method creates elements for SVG linear gradient.\n * @param {string} linearGradientId This argument is id attribute for `SVGLinearGradientElement`.\n * @return {SVGDefsElement} This is returned as the instance of `SVGDefsElement`.\n */\n createSVGLinearGradient(linearGradientId) {\n const defs = document.createElementNS(Visualizer.XMLNS, 'defs');\n const linearGradient = document.createElementNS(Visualizer.XMLNS, 'linearGradient');\n\n linearGradient.setAttribute('id', String(linearGradientId));\n linearGradient.setAttribute('x1', '0%');\n linearGradient.setAttribute('y1', '0%');\n linearGradient.setAttribute('x2', '0%');\n linearGradient.setAttribute('y2', '100%');\n\n for (const gradients of this.styles.grad) {\n const stop = document.createElementNS(Visualizer.XMLNS, 'stop');\n\n stop.setAttribute('offset', gradients.offset);\n stop.setAttribute('stop-color', gradients.color);\n\n linearGradient.appendChild(stop);\n }\n\n defs.appendChild(linearGradient);\n\n return defs;\n }\n\n /**\n * This method creates string for font.\n * @return {string} This is returned as string for font.\n */\n createFontString() {\n const { size, style, family } = this.styles.font;\n\n return `${style} ${size} \"${family}\"`;\n }\n\n /** @abstract */\n drawOnCanvas() {\n return this;\n }\n\n /** @abstract */\n drawBySVG() {\n return this;\n }\n\n /**\n * This method clears graphics.\n */\n clear() {\n if (this.context) {\n const { width, height } = this.canvas;\n\n this.context.clearRect(0, 0, width, height);\n }\n\n if (this.svg) {\n this.svg.innerHTML = '';\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser Visualizer]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing audio wave in overview of time domain.\n * @constructor\n * @extends {Visualizer}\n */\nexport class TimeOverview extends Visualizer {\n static SVG_CURRENT_TIME_CLASS_NAME = 'xsound-svg-current-time';\n static SVG_SPRITE_CLASS_NAME = 'xsound-svg-sprite';\n static DRAG_MODE_UPDATE = 'update';\n static DRAG_MODE_SPRITE = 'sprite';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = null;\n this.length = 0;\n\n this.currentTime = 'rgba(0, 0, 0, 0.5)'; // This style is used for the rectangle that displays current time of audio\n this.sprite = 'rgba(255, 255, 255, 0.25)'; // This style is used for the rectangle that displays sprite range\n this.plotInterval = 0.0625; // Draw wave at intervals of this value [sec]\n this.textInterval = 60; // Draw text at intervals of this value [sec]\n\n this.isDown = false;\n\n this.mode = TimeOverview.DRAG_MODE_UPDATE; // or 'sprite'\n\n this.offsetX = 0;\n this.startTime = 0;\n this.endTime = 0;\n\n this.onStart = this.onStart.bind(this);\n this.onMove = this.onMove.bind(this);\n this.onEnd = this.onEnd.bind(this);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'currenttime':\n if (value === undefined) {\n return this.currentTime;\n }\n\n this.currentTime = String(value).toLowerCase();\n\n break;\n case 'sprite':\n if (value === undefined) {\n return this.sprite;\n }\n\n this.sprite = String(value).toLowerCase();\n\n break;\n case 'plotinterval':\n case 'textinterval':\n if (value === undefined) {\n return this[k.replace('interval', 'Interval')];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k.replace('interval', 'Interval')] = v;\n }\n\n break;\n case 'mode':\n if (value === undefined) {\n return this.mode;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === TimeOverview.DRAG_MODE_UPDATE) || (v === TimeOverview.DRAG_MODE_SPRITE)) {\n this.mode = v;\n\n // Clear for Audio Sprite\n this.offsetX = 0;\n this.startTime = 0;\n this.endTime = 0;\n\n if (this.svg instanceof SVGElement) {\n const rect = this.svg.querySelector(`.${TimeOverview.SVG_SPRITE_CLASS_NAME}`);\n\n if (rect instanceof SVGElement) {\n this.svg.removeChild(rect);\n }\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws audio wave in overview of time domain to Canvas.\n * @param {Float32Array} data This argument is data for drawing.\n * @return {TimeOverview} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw wave at intervals of `this.plotInterval`\n const nPlotInterval = Math.floor(this.plotInterval * this.sampleRate);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n this.drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, nPlotInterval);\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.floor((i / this.sampleRate) / 60)} min`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n }\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = context.getImageData(0, 0, width, height);\n this.length = data.length;\n\n // This rectangle displays current time of audio\n context.fillStyle = this.currentTime;\n context.fillRect(this.styles.left, this.styles.top, 1, innerHeight);\n\n return this;\n }\n\n /**\n * This method draws audio wave in overview of time domain to SVG.\n * @param {Float32Array} data This argument is data for drawing.\n * @return {TimeOverview} This is returned for method chain.\n * @override\n */\n drawBySVG(data) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw wave at intervals of `this.plotInterval`\n const nPlotInterval = Math.floor(this.plotInterval * this.sampleRate);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin drawing\n svg.appendChild(this.drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, nPlotInterval, Visualizer.SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW));\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / len) * innerWidth) + this.styles.left;\n const t = Math.floor((i / this.sampleRate) / 60) + ' min';\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // This rectangle displays current time of audio\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.classList.add(TimeOverview.SVG_CURRENT_TIME_CLASS_NAME);\n\n rect.setAttribute('y', (this.styles.top + 1));\n rect.setAttribute('height', (innerHeight - 1));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.currentTime);\n\n svg.appendChild(rect);\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = svg;\n this.length = data.length;\n\n return this;\n }\n\n /**\n * This method draws current time of audio on Canvas or SVG.\n * @param {number} time This argument is current time of audio.\n * @return {TimeOverview} This is returned for method chain.\n */\n update(time) {\n const t = parseFloat(time);\n\n if (isNaN(t) || (t < 0)) {\n return this;\n }\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n if (this.savedImage instanceof ImageData) {\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const x = ((t * this.sampleRate) / this.length) * innerWidth;\n\n context.clearRect(0, 0, width, height);\n context.putImageData(this.savedImage, 0, 0);\n\n if (this.mode === TimeOverview.DRAG_MODE_UPDATE) {\n context.fillStyle = this.currentTime;\n context.fillRect(this.styles.left, (this.styles.top + 1), x, (innerHeight - 1));\n } else if (this.mode === TimeOverview.DRAG_MODE_SPRITE) {\n if (this.endTime !== 0) {\n const baseX = Math.floor(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.length) * innerWidth);\n context.fillStyle = this.sprite;\n\n if (x >= this.offsetX) {\n context.fillRect((this.styles.left + this.offsetX), (this.styles.top + 1), baseX, (innerHeight - 1));\n } else {\n context.fillRect((this.styles.left + this.offsetX - baseX), (this.styles.top + 1), baseX, (innerHeight - 1));\n }\n }\n\n context.fillStyle = this.currentTime;\n\n if (x >= this.offsetX) {\n context.fillRect((this.styles.left + this.offsetX), (this.styles.top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n } else {\n context.fillRect((this.styles.left + x), (this.styles.top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n }\n }\n }\n\n break;\n case Visualizer.SVG:\n const rect = this.svg.querySelector(`.${TimeOverview.SVG_CURRENT_TIME_CLASS_NAME}`);\n\n if (rect instanceof SVGElement) {\n const width = parseInt(this.svg.getAttribute('width'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const x = ((t * this.sampleRate) / this.length) * innerWidth;\n\n if (this.mode === TimeOverview.DRAG_MODE_UPDATE) {\n rect.setAttribute('x', this.styles.left);\n rect.setAttribute('width', x);\n // rect.setAttribute('transform', `translate(${x} 0)`);\n rect.setAttribute('aria-label', 'current time');\n } else if (this.mode === TimeOverview.DRAG_MODE_SPRITE) {\n if (this.endTime !== 0) {\n const baseRect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n baseRect.classList.add(TimeOverview.SVG_SPRITE_CLASS_NAME);\n\n if (this.svg.lastElementChild.previousElementSibling instanceof SVGElement) {\n this.svg.removeChild(this.svg.lastElementChild.previousElementSibling);\n }\n\n const baseX = Math.floor(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.length) * innerWidth);\n\n baseRect.setAttribute('y', (this.styles.top + 1));\n baseRect.setAttribute('height', rect.getAttribute('height'));\n baseRect.setAttribute('stroke', 'none');\n baseRect.setAttribute('fill', this.sprite);\n baseRect.setAttribute('aria-label', 'current time');\n\n if (x >= this.offsetX) {\n baseRect.setAttribute('x', (this.styles.left + this.offsetX));\n } else {\n baseRect.setAttribute('x', (this.styles.left + this.offsetX - baseX));\n }\n\n baseRect.setAttribute('width', baseX);\n\n this.svg.appendChild(baseRect);\n this.svg.appendChild(rect);\n }\n\n if (x >= this.offsetX) {\n rect.setAttribute('x', (this.styles.left + this.offsetX));\n } else {\n rect.setAttribute('x', (this.styles.left + x));\n }\n\n rect.setAttribute('width', Math.abs(x - this.offsetX));\n rect.setAttribute('aria-label', 'sprite time');\n }\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method registers event listener for setting current time by drag.\n * @param {function} callback This argument is invoked when current time is changed.\n * @return {TimeOverview} This is returned for method chain.\n */\n drag(callback) {\n let drawNode = null;\n\n let start = '';\n let move = '';\n let end = '';\n\n // Touch Panel ?\n if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) {\n start = 'touchstart';\n move = 'touchmove';\n end = 'touchend';\n } else {\n start = 'mousedown';\n move = 'mousemove';\n end = 'mouseup';\n }\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n drawNode = this.canvas;\n break;\n case Visualizer.SVG:\n drawNode = this.svg;\n break;\n default:\n return this;\n }\n\n this.callback = Object.prototype.toString.call(callback) === '[object Function]' ? callback : () => {};\n\n drawNode.removeEventListener(start, this.onStart, true);\n drawNode.removeEventListener(move, this.onMove, true);\n window.removeEventListener(end, this.onEnd, true);\n\n drawNode.addEventListener(start, this.onStart, true);\n drawNode.addEventListener(move, this.onMove, true);\n window.addEventListener(end, this.onEnd, true);\n\n return this;\n }\n\n /**\n * This method draws the rectangle for current time of audio.\n * @param {Event} event This argument is the instance of `Event`.\n * @param {number} offsetX This argument is X coordinate on Canvas or SVG.\n * @param {function} callback This argument is invoked when the rectangle is drawn.\n * @return {TimeOverview} This is returned for method chain.\n */\n draw(event, type, offsetX) {\n let offsetLeft = 0;\n let width = 0;\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n offsetLeft = this.canvas.offsetLeft;\n width = this.canvas.width;\n break;\n case Visualizer.SVG:\n offsetLeft = this.svg.parentNode.offsetLeft;\n width = parseInt(this.svg.getAttribute('width'), 10);\n break;\n default:\n break;\n }\n\n let x = offsetX - (offsetLeft + this.styles.left);\n\n if (this.canvas.parentNode instanceof Element) {\n x += this.canvas.parentNode.scrollLeft;\n }\n\n width -= (this.styles.left + this.styles.right);\n\n // Exceed ?\n if (x < 0) { x = 0; }\n if (x > width) { x = width; }\n\n const plot = (x / width) * this.length;\n const time = plot / this.sampleRate;\n\n if ((type === 'mousedown') || (type === 'touchstart')) {\n this.offsetX = x;\n this.startTime = time;\n this.endTime = 0;\n }\n\n if ((type === 'mouseup') || (type === 'touchend')) {\n this.endTime = time;\n }\n\n this.update(time);\n\n if (this.startTime <= time) {\n this.callback(event, this.startTime, time, this.mode, true);\n } else if (this.startTime > time) {\n this.callback(event, time, this.startTime, this.mode, false);\n }\n\n return this;\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onStart(event) {\n this.draw(event, event.type, this.getOffsetX(event));\n this.isDown = true;\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onMove(event) {\n if (!this.isDown) {\n return;\n }\n\n event.preventDefault(); // for Touch Panel\n this.draw(event, event.type, this.getOffsetX(event));\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onEnd(event) {\n if (!this.isDown) {\n return;\n }\n\n this.draw(event, event.type, this.getOffsetX(event));\n\n this.isDown = false;\n }\n\n /**\n * This method returns X coordinate from `Event` object.\n * @param {Event} event This argument is the instance of `Event`.\n * @return {number} This is returned as X coordinate.\n */\n getOffsetX(event) {\n if (event.pageX) {\n return event.pageX;\n }\n\n if (event.touches[0]) {\n return event.touches[0].pageX;\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser TimeOverview]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing sound wave in time domain.\n * @constructor\n * @extends {Visualizer}\n */\nexport class Time extends Visualizer {\n static UINT = 'uint';\n static FLOAT = 'float';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n this.type = Time.UINT; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\n this.textInterval = 0.005; // Draw text at intervals this value [sec]\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === Time.UINT) || (v === Time.FLOAT)) {\n this.type = v;\n }\n\n break;\n case 'textinterval':\n if (value === undefined) {\n return this.textInterval;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.textInterval = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in time domain to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @return {Time} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n switch (this.type) {\n case Time.FLOAT:\n this.drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle);\n break;\n case Time.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = (0.5 - (data[i] / 255)) * innerHeight;\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = (innerHeight / 2) + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, middle, this.styles.width, y);\n }\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.ceil((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.ceil((i / this.sampleRate) * 1000)} ms`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in time domain to SVG.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @return {Time} This is returned for method chain.\n * @override\n */\n drawBySVG(data) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Begin drawing\n svg.innerHTML = '';\n\n // Begin drawing\n switch (this.type) {\n case Time.FLOAT:\n svg.appendChild(this.drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, null, Visualizer.SVG_LINEAR_GRADIENT_ID_TIME));\n break;\n case Time.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case 'rect':\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(Visualizer.SVG_LINEAR_GRADIENT_ID_TIME);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0, len = data.length; i < len; i++) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((data[i] / 255) - 0.5) * innerHeight;\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', middle);\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${Visualizer.SVG_LINEAR_GRADIENT_ID_TIME})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.ceil((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.ceil((i / this.sampleRate) * 1000)} ms`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser Time]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing sound wave in frequency domain (spectrum).\n * @constructor\n * @extends {Visualizer}\n */\nexport class FFT extends Visualizer {\n static UINT = 'uint';\n static FLOAT = 'float';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n this.type = FFT.UINT; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\n this.size = 256; // Range for drawing\n this.textInterval = 1000; // Draw text at intervals of this value [Hz]\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === FFT.UINT) || (v === FFT.FLOAT)) {\n this.type = v;\n }\n\n break;\n case 'size':\n if (value === undefined) {\n return this.size;\n }\n\n v = parseInt(value, 10);\n min = 0;\n max = 1024; // `AnalyserNode#fftSize` max 2048 -> half 1024\n\n if ((v > min) && (v <= max)) {\n this.size = v;\n }\n\n break;\n case 'textinterval':\n if (value === undefined) {\n return this.textInterval;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.textInterval = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in frequency domain (spectrum) to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is in order to determine the range of drawing. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine the range of drawing. The default value is -30 dB.\n * @return {FFT} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data, minDecibels, maxDecibels) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const mindB = parseFloat(minDecibels);\n const maxdB = parseFloat(maxDecibels);\n\n const range = maxdB - mindB;\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n\n const drawnSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const fsDivN = this.sampleRate / (2 * data.length);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval / fsDivN);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n switch (this.type) {\n case FFT.FLOAT:\n // Set style\n context.strokeStyle = (this.styles.wave !== 'gradient') ? this.styles.wave : 'rgba(0, 0, 255, 1.0)'; // line only\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = (Math.abs(data[i] - maxdB) * (innerHeight / range)) + this.styles.top; // [dB] * [px / dB] = [px]\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case FFT.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n context.beginPath();\n\n // Draw wave\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = -1 * ((data[i] / 255) * innerHeight);\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = innerHeight + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, (innerHeight + this.styles.top), this.styles.width, y);\n }\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0; i < drawnSize; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n\n const f = Math.floor(this.textInterval * (i / nTextInterval));\n const t = (f < 1000) ? `${f} Hz` : `${String(f / 1000).slice(0, 3)} kHz`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n switch (this.type) {\n case FFT.FLOAT:\n for (let i = mindB; i <= maxdB; i += 10) {\n const t = `${i} dB`;\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor(((-1 * (i - maxdB)) / range) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n\n break;\n case FFT.UINT:\n default:\n const texts = ['0.00', '0.25', '0.50', '0.75', '1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = ((1 - parseFloat(t)) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in frequency domain (spectrum) to SVG.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is in order to determine the range of drawing. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine the range of drawing. The default value is -30 dB.\n * @return {FFT} This is returned for method chain.\n * @override\n */\n drawBySVG(data, minDecibels, maxDecibels) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const mindB = parseFloat(minDecibels);\n const maxdB = parseFloat(maxDecibels);\n\n const range = maxdB - mindB;\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n\n const drawnSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (sample rate / FFT size)\n const fsDivN = this.sampleRate / (2 * data.length);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval / fsDivN);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin drawing\n switch (this.type) {\n case FFT.FLOAT:\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0; i < drawnSize; i++) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor(-1 * (data[i] - maxdB) * (innerHeight / range)) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', ((this.styles.wave !== 'gradient') ? this.styles.wave : 'rgba(0, 0, 255, 1.0)')); // line only\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case FFT.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0; i < drawnSize; i++) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case 'rect':\n // Draw wave\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(Visualizer.SVG_LINEAR_GRADIENT_ID_FFT);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0; i < drawnSize; i++) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor((data[i] / 255) * innerHeight);\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', (this.styles.top + innerHeight));\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${this.styles.top + innerHeight})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${Visualizer.SVG_LINEAR_GRADIENT_ID_FFT})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0; i < drawnSize; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n\n const f = Math.floor(this.textInterval * (i / nTextInterval));\n const t = (f < 1000) ? `${f} Hz` : `${String(f / 1000).slice(0, 3)} kHz`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n switch (this.type) {\n case FFT.FLOAT:\n for (let i = mindB; i <= maxdB; i += 10) {\n const t = `${i}dB`;\n const x = this.styles.left;\n const y = Math.floor(((-1 * (i - maxdB)) / range) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n\n break;\n case FFT.UINT:\n default:\n const texts = ['0.00', '0.25', '0.50', '0.75', '1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = ((1 - parseFloat(t)) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser FFT]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\nimport { TimeOverview } from './TimeOverview';\nimport { Time } from './Time';\nimport { FFT } from './FFT';\n\n/**\n * This private class manages 3 private classes (`TimeOverview`, `Time`, `FFT`) for drawing sound wave.\n * @constructor\n */\nexport class Analyser extends Connectable {\n /**\n * @param {AudioContext} context This argument is This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n super();\n\n this.analyser = context.createAnalyser();\n this.input = context.createGain();\n\n // GainNode (Input) -> AnalyserNode\n this.input.connect(this.analyser);\n\n this.timeOverviewL = new TimeOverview(context.sampleRate);\n this.timeOverviewR = new TimeOverview(context.sampleRate);\n this.time = new Time(context.sampleRate);\n this.fft = new FFT(context.sampleRate);\n\n // Set default value\n this.analyser.fftSize = 2048;\n this.analyser.minDecibels = -100;\n this.analyser.maxDecibels = -30;\n this.analyser.smoothingTimeConstant = 0.8;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Analyser} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'fftsize':\n if (value === undefined) {\n return this.analyser.fftSize;\n }\n\n v = parseInt(value, 10);\n\n switch (v) {\n case 32:\n case 64:\n case 128:\n case 256:\n case 512:\n case 1024:\n case 2048:\n this.analyser.fftSize = v;\n break;\n default:\n break;\n }\n\n break;\n case 'frequencybincount':\n return this.analyser.frequencyBinCount; // Getter only\n case 'mindecibels':\n if (value === undefined) {\n return this.analyser.minDecibels;\n }\n\n v = parseFloat(value);\n max = -30;\n\n if (v < max) {\n this.analyser.minDecibels = v;\n }\n\n break;\n case 'maxdecibels':\n if (value === undefined) {\n return this.analyser.maxDecibels;\n }\n\n v = parseFloat(value);\n min = -100;\n\n if (v > min) {\n this.analyser.maxDecibels = v;\n }\n\n break;\n case 'smoothingtimeconstant':\n if (value === undefined) {\n return this.analyser.smoothingTimeConstant;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.analyser.smoothingTimeConstant = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method creates data for drawing and executes drawing.\n * @param {string} domain This argument is one of 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @param {number} channel This argument is number greater than or equal to 0.\n * @param {AudioBuffer} buffer This argument is the instance of `AudioBuffer`. The data for drawing audio wave in overview of time domain is gotten from this argument.\n * @return {Analyser} This is returned for method chain.\n */\n start(domain, channel, buffer) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n const c = parseInt(channel, 10);\n\n let data = null;\n\n switch (d) {\n case 'timeoverview':\n switch (c) {\n case 0:\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > c) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(c));\n this.timeOverviewL.start(data);\n }\n }\n\n break;\n case 1:\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > c) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(c));\n this.timeOverviewR.start(data);\n }\n }\n\n break;\n default:\n break;\n }\n\n break;\n case 'timeoverviewl':\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > 0) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(0));\n this.timeOverviewL.start(data);\n }\n }\n\n break;\n case 'timeoverviewr':\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > 1) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(1));\n this.timeOverviewR.start(data);\n }\n }\n\n break;\n case 'time':\n if (this.time.param('type') === 'uint') {\n data = new Uint8Array(this.analyser.fftSize);\n this.analyser.getByteTimeDomainData(data);\n this.time.start(data);\n } else {\n data = new Float32Array(this.analyser.fftSize);\n this.analyser.getFloatTimeDomainData(data);\n this.time.start(data);\n }\n\n if (this.time.param('interval') === 'auto') {\n this.time.timerid = window.requestAnimationFrame(() => {\n this.start(domain);\n });\n } else {\n this.time.timerid = window.setTimeout(() => {\n this.start(domain);\n }, this.time.param('interval'));\n }\n\n break;\n case 'fft':\n if (this.fft.param('type') === 'uint') {\n data = new Uint8Array(this.analyser.frequencyBinCount);\n this.analyser.getByteFrequencyData(data);\n this.fft.start(data);\n } else {\n data = new Float32Array(this.analyser.frequencyBinCount);\n this.analyser.getFloatFrequencyData(data);\n this.fft.start(data, this.analyser.minDecibels, this.analyser.maxDecibels);\n }\n\n if (this.fft.param('interval') === 'auto') {\n this.fft.timerid = window.requestAnimationFrame(() => {\n this.start(domain);\n });\n } else {\n this.fft.timerid = window.setTimeout(() => {\n this.start(domain);\n }, this.fft.param('interval'));\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method stops drawing.\n * @param {string} domain This argument is one of 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @return {Analyser} This is returned for method chain.\n */\n stop(domain) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n\n switch (d) {\n case 'timeoverviewl':\n case 'timeoverviewr':\n break;\n case 'time':\n if (this.time.param('interval') === 'auto') {\n window.cancelAnimationFrame(this.time.timerid);\n } else {\n window.clearTimeout(this.time.timerid);\n }\n\n this.time.timerid = null;\n\n break;\n case 'fft':\n if (this.fft.param('interval') === 'auto') {\n window.cancelAnimationFrame(this.fft.timerid);\n } else {\n window.clearTimeout(this.fft.timerid);\n }\n\n this.fft.timerid = null;\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method selects domain for drawing.\n * @param {string} domain This argument is one of 'timeoverview', 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @param {number} channel This argument is number greater than or equal to 0.\n * @return {TimeOverview|Time|FFT|Analyser} This value is the instance of selected class.\n */\n domain(domain, channel) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n const c = parseInt(channel, 10);\n\n switch (d) {\n case 'timeoverview':\n switch (c) {\n case 0:\n return this.timeOverviewL;\n case 1:\n return this.timeOverviewR;\n default:\n return this;\n }\n case 'timeoverviewl':\n case 'timeoverviewr':\n return this[`timeOverview${d.slice(-1).toUpperCase()}`];\n case 'time':\n case 'fft' :\n return this[d];\n default:\n return this;\n }\n }\n\n /**\n * This method gets the instance of `AnalyserNode`.\n * @return {AnalyserNode}\n */\n get() {\n return this.analyser;\n }\n\n /** @override */\n get INPUT() {\n return this.input;\n }\n\n /** @override */\n get OUTPUT() {\n return this.input;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser]';\n }\n}\n","'use strict';\n\n/**\n * This class is model for a recording track.\n * Namely, this class has the recorded sound data.\n * @constructor\n */\nexport class Track {\n /**\n * @param {number} trackNumber This argument is a track number greater than or equal to 0.\n */\n constructor(trackNumber) {\n this.trackNumber = trackNumber >= 0 ? trackNumber : 0;\n this.dataBlocks = []; /** @type {Array.<Float32Array>} */\n }\n\n /**\n * This method returns the array that contains the recorded sound data.\n * @return {Array.<Float32Array>} This is returned as the array that contains `Float32Array`.\n */\n get() {\n return this.dataBlocks;\n }\n\n /**\n * This method appends the recorded sound data as `Float32Array`\n * @param {Float32Array} dataBlock This argument is the instance of `Float32Array` that has the recorded sound data.\n */\n append(dataBlock) {\n if (dataBlock instanceof Float32Array) {\n this.dataBlocks.push(dataBlock);\n }\n }\n\n /**\n * This method determines whether contains the recorded sound data.\n * @return {boolean} If the track has the recorded data, this value is `true`. Otherwise, this value is `false`.\n */\n has() {\n return this.dataBlocks.length > 0;\n }\n\n /**\n * This method clears data blocks.\n */\n clear() {\n this.dataBlocks.length = 0;\n }\n}\n","'use strict';\n\nimport { Track } from './Track';\n\n/**\n * This class is model for a recording channel.\n * @constructor\n */\nexport class Channel {\n /**\n * @param {number} channelNumber This argument is a channel number greater than or equal to 0.\n */\n constructor(channelNumber) {\n this.channelNumber = channelNumber >= 0 ? channelNumber : 0;\n\n this.tracks = []; /** @type {Array.<Float32Array>} */\n this.channelGain = 1;\n }\n\n /**\n * This method returns the designated track or the array that contains tracks.\n * @param {number} trackNumber This argument is the target track number.\n * @return {Track|Array.<Track>} This is returned as the designated track or the array that contains the instances of `Track`.\n */\n get(trackNumber) {\n const t = parseInt(trackNumber, 10);\n\n if ((t >= 0) && (t < this.tracks.length)) {\n return this.tracks[t];\n }\n\n return this.tracks;\n }\n\n /**\n * This method appends the instance of `Track`.\n * @param {Track} track This argument is the instance of `Track` as a recording track.\n */\n append(track) {\n if (track instanceof Track) {\n this.tracks.push(track);\n }\n }\n\n /**\n * This method returns the number of tracks.\n * @return {number} This is returned as the number of tracks.\n */\n length() {\n return this.tracks.length;\n }\n\n /**\n * This method gets or sets the channel gain.\n * @param {number} gain This argument is the channel gain. If this argument is omitted, This method is getter.\n * @return {number} This is returned as the channel gain in the case of getter.\n */\n gain(gain) {\n if (gain === undefined) {\n return this.channelGain;\n }\n\n const g = parseFloat(gain);\n\n if ((g >= 0) && (g <= 1)) {\n this.channelGain = g;\n }\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\nimport { Track } from './Track';\nimport { Channel } from './Channel';\n\n/**\n * This private class defines properties for multi track recording.\n * @constructor\n */\nexport class Recorder extends Connectable {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @param {number} numberOfInputs This argument is the number of inputs for `ScriptProcessorNode`.\n * @param {number} numberOfOutputs This argument the number of outputs for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize, numberOfInputs, numberOfOutputs) {\n super();\n\n this.sampleRate = context.sampleRate;\n\n this.context = context;\n this.processor = context.createScriptProcessor(bufferSize, numberOfInputs, numberOfOutputs);\n\n this.channels = [new Channel(0), new Channel(1)]; /** @type {Array.<Channel>} */\n\n this.activeTrack = -1; // There is not any active track in the case of -1\n this.paused = true; // for preventing from the duplicate `onaudioprocess` event (`start` method)\n }\n\n /**\n * This method sets the max number of tracks.\n * @param {number} numberOfTracks This argument is the max number of tracks. The default value is 1.\n * @return {Recorder} This is returned for method chain.\n */\n setup(numberOfTracks) {\n const n = parseInt(numberOfTracks, 10);\n\n if (n > 0) {\n for (let i = 0; i < n; i++) {\n this.channels[0].append(new Track(i));\n this.channels[1].append(new Track(i));\n }\n } else {\n this.channels[0].append(new Track(0));\n this.channels[1].append(new Track(0));\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Recorder} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n switch (k) {\n case '0' :\n case 'left':\n if (value === undefined) {\n return this.channels[0].gain();\n }\n\n this.channels[0].gain(value);\n break;\n case '1' :\n case 'right':\n if (value === undefined) {\n return this.channels[1].gain();\n }\n\n this.channels[1].gain(value);\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method selects active track.\n * @param {number} trackNumber This argument is in order to select active track.\n * @return {Recorder} This is returned for method chain.\n */\n ready(trackNumber) {\n if (this.hasTrack(trackNumber)) {\n this.activeTrack = trackNumber;\n } else {\n this.activeTrack = -1;\n }\n\n return this;\n }\n\n /**\n * This method starts recording. If there is not any active track, this method stops `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Recorder} This is returned for method chain.\n */\n start() {\n if ((this.activeTrack !== -1) && this.paused) {\n this.paused = false;\n\n const gainL = this.channels[0].gain();\n const gainR = this.channels[1].gain();\n\n const trackL = this.channels[0].get(this.activeTrack);\n const trackR = this.channels[1].get(this.activeTrack);\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n if (this.activeTrack !== -1) {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n\n const recordedLs = new Float32Array(bufferSize);\n const recordedRs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n recordedLs[i] = gainL * inputLs[i];\n recordedRs[i] = gainR * inputRs[i];\n }\n\n trackL.append(recordedLs);\n trackR.append(recordedRs);\n } else {\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method turns off the all of tracks, and stops `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Recorder} This is returned for method chain.\n */\n stop() {\n this.activeTrack = -1; // Flag becomes inactive\n this.paused = true;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n return this;\n }\n\n /**\n * This method determines whether the designated channel number is valid.\n * @param {number} channelNumber This argument is channel number for validation.\n * @return {boolean} If the designated channel is valid range, this value is `true`. Otherwise, this value is `false`.\n */\n hasChannel(channelNumber) {\n const c = parseInt(channelNumber, 10);\n\n return (c >= 0) && (c < this.channels.length);\n }\n\n /**\n * This method determines whether the designated track number is valid.\n * @param {number} trackNumber This argument is track number for validation.\n * @return {boolean} If the designated track is valid range, this value is `true`. Otherwise, this value is `false`.\n */\n hasTrack(trackNumber) {\n const t = parseInt(trackNumber, 10);\n\n return (t >= 0) && this.channels.every(channel => t < channel.length());\n }\n\n /**\n * This method determines whether the track has a recorded data.\n * @param {number} channelNumber This argument is the target channel number.\n * @param {number} trackNumber This argument is the target track number.\n * @return {boolean} If there is the track that has a recorded data at least, this method returns true. Otherwise this value is `false`.\n */\n has(channelNumber, trackNumber) {\n if (!this.hasChannel(channelNumber)) {\n return this.channels.some(channel => {\n const tracks = channel.get();\n\n return tracks.some(track => track.has());\n });\n }\n\n const c = parseInt(channelNumber, 10);\n\n const tracks = this.channels[c].get();\n\n if (!this.hasTrack(trackNumber)) {\n return tracks.some(track => track.has());\n }\n\n const t = parseInt(trackNumber, 10);\n\n return tracks[t].has();\n }\n\n /**\n * This method determines whether active track exists.\n * @return {number} This is returned as active track.\n */\n get() {\n return this.activeTrack;\n }\n\n /**\n * This method flats recorded sounds in track.\n * @param {number} channelNumber This argument is the channel number for mixing.\n * @param {number} trackNumber This argument is track number.\n * @return {Float32Array} This is returned as array for flatten sound.\n */\n flatTrack(channelNumber, trackNumber) {\n if (!this.hasChannel(channelNumber) || !this.hasTrack(trackNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const track = channel.get(trackNumber);\n const dataBlocks = track.get();\n const bufferSize = this.processor.bufferSize;\n\n const flattenTrack = new Float32Array(dataBlocks.length * bufferSize);\n\n for (let i = 0, len = dataBlocks.length; i < len; i++) {\n const dataBlock = dataBlocks[i];\n\n for (let j = 0; j < bufferSize; j++) {\n flattenTrack[(i * bufferSize) + j] = dataBlock[j];\n }\n }\n\n return flattenTrack;\n }\n\n /**\n * This method synthesizes recorded sounds in track.\n * @param {number} channelNumber This argument is the channel number for mixing.\n * @return {Float32Array} This is returned as array for synthesized sound.\n */\n mixTrack(channelNumber) {\n if (!this.hasChannel(channelNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const tracks = channel.get();\n const bufferSize = this.processor.bufferSize;\n\n let sum = 0;\n let numberOfElements = 0;\n let currentBlock = 0;\n let index = 0;\n\n // Calculate sound data size\n let numberOfMaxBlocks = 0;\n\n // Search the max number of `Float32Array`'s each track\n for (const track of tracks) {\n const dataBlocks = track.get();\n\n if (numberOfMaxBlocks < dataBlocks.length) {\n numberOfMaxBlocks = dataBlocks.length;\n }\n }\n\n const mixedValues = new Float32Array(numberOfMaxBlocks * bufferSize);\n\n while (true) {\n for (let currentTrack = 0, len = tracks.length; currentTrack < len; currentTrack++) {\n const track = tracks[currentTrack];\n const dataBlocks = track.get();\n const dataBlock = dataBlocks[currentBlock];\n\n if (dataBlock instanceof Float32Array) {\n sum += dataBlock[index];\n numberOfElements++;\n }\n }\n\n if (numberOfElements <= 0) {\n return mixedValues;\n }\n\n const offset = currentBlock * bufferSize;\n\n // Average\n mixedValues[offset + index] = sum / numberOfElements;\n\n // Clear\n sum = 0;\n numberOfElements = 0;\n\n // Next data\n if (index < (bufferSize - 1)) {\n // Next element in Float32Array\n index++;\n } else {\n // Next Float32Array\n currentBlock++;\n index = 0;\n }\n }\n }\n\n /**\n * This method clears recorded sound of the designated track.\n * @param {number} trackNumber This argument is track for clearing.\n * @return {Recorder} This is returned for method chain.\n */\n clear(trackNumber) {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n const t = parseInt(trackNumber, 10);\n\n if (t === -1) {\n for (const channel of this.channels) {\n const tracks = channel.get();\n\n for (const track of tracks) {\n track.clear();\n }\n }\n } else {\n if (this.hasTrack(t)) {\n for (const channel of this.channels) {\n const track = channel.get(t);\n\n track.clear();\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method creates WAVE file as Object URL or Data URL.\n * @param {number} trackNumber This argument is the track number for mixing.\n * @param {number} numberOfChannels This argument is in order to select stereo or monaural of WAVE file. The default value is 2.\n * @param {number} qbit This argument is quantization bit of PCM. The default value is 16 (bit).\n * @param {string} type This argument is one of 'blob', 'objecturl', 'base64', 'dataurl'.\n * @return {Blob|string} This is returned as `Blob` or Object URL or Base64 or Data URL for WAVE file.\n */\n create(trackNumber, numberOfChannels, qbit, type) {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n /** @type {Float32Array} */\n let soundLs = null;\n\n /** @type {Float32Array} */\n let soundRs = null;\n\n if ((trackNumber === -1) && this.has()) {\n soundLs = this.mixTrack(0);\n soundRs = this.mixTrack(1);\n } else if (this.has(0, trackNumber) && this.has(1, trackNumber)) {\n soundLs = this.flatTrack(0, trackNumber);\n soundRs = this.flatTrack(1, trackNumber);\n } else {\n // Sound data does not exists\n return '';\n }\n\n // PCM parameters\n const CHANNEL = (numberOfChannels === 1) ? 1 : 2;\n const QBIT = (qbit === 8) ? 8 : 16;\n const SIZE = (CHANNEL === 1) ? Math.min(soundLs.length, soundRs.length) : (2 * Math.min(soundLs.length, soundRs.length));\n\n // Parameters for WAVE file\n const FMT_CHUNK = 28;\n const DATA_CHUNK = 8 + (SIZE * (QBIT / 8));\n const CHUNK_SIZE = 36 + (SIZE * (QBIT / 8));\n const RIFF_CHUNK = 8 + (FMT_CHUNK + DATA_CHUNK);\n const RATE = this.sampleRate;\n const BPS = RATE * CHANNEL * (QBIT / 8);\n const DATA_SIZE = SIZE * (QBIT / 8);\n\n /** @type {Uint8Array|Int16Array} */\n let sounds = null;\n\n switch (QBIT) {\n case 8:\n sounds = new Uint8Array(SIZE);\n\n for (let i = 0; i < SIZE; i++) {\n // Convert 8 bit unsigned integer (-1 -> 0, 0 -> 128, 1 -> 255)\n let binary = 0;\n\n if ((i % CHANNEL) === 0) {\n binary = ((soundLs[Math.floor(i / CHANNEL)] + 1) / 2) * (Math.pow(2, 8) - 1); // Left channel\n } else {\n binary = ((soundRs[Math.floor(i / CHANNEL)] + 1) / 2) * (Math.pow(2, 8) - 1); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (Math.pow(2, 8) - 1)) { binary = (Math.pow(2, 8) - 1); }\n if (binary < (Math.pow(2, 0) - 1)) { binary = (Math.pow(2, 0) - 1); }\n\n sounds[i] = binary;\n }\n\n break;\n case 16:\n sounds = new Int16Array(SIZE);\n\n for (let i = 0; i < SIZE; i++) {\n // Convert 16 bit integer (-1 -> -32768, 0 -> 0, 1 -> 32767)\n let binary = 0;\n\n if ((i % CHANNEL) === 0) {\n binary = soundLs[Math.floor(i / CHANNEL)] * Math.pow(2, 15); // Left channel\n } else {\n binary = soundRs[Math.floor(i / CHANNEL)] * Math.pow(2, 15); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (+Math.pow(2, 15) - 1)) { binary = +Math.pow(2, 15) - 1; }\n if (binary < (-Math.pow(2, 15) - 0)) { binary = -Math.pow(2, 15) - 0; }\n\n sounds[i] = binary;\n }\n\n break;\n default:\n break;\n }\n\n const wave = new Uint8Array(44 + DATA_SIZE);\n\n wave[0] = 0x52; // 'R'\n wave[1] = 0x49; // 'I'\n wave[2] = 0x46; // 'F'\n wave[3] = 0x46; // 'F'\n\n wave[4] = (CHUNK_SIZE >> 0) & 0xFF;\n wave[5] = (CHUNK_SIZE >> 8) & 0xFF;\n wave[6] = (CHUNK_SIZE >> 16) & 0xFF;\n wave[7] = (CHUNK_SIZE >> 24) & 0xFF;\n\n wave[8] = 0x57; // 'W'\n wave[9] = 0x41; // 'A'\n wave[10] = 0x56; // 'V'\n wave[11] = 0x45; // 'E'\n\n // fmt chunk\n wave[12] = 0x66; // 'f'\n wave[13] = 0x6D; // 'm'\n wave[14] = 0x74; // 't'\n wave[15] = 0x20; // ' '\n\n wave[16] = 16;\n wave[17] = 0;\n wave[18] = 0;\n wave[19] = 0;\n\n wave[20] = 1;\n wave[21] = 0;\n\n // fmt chunk -> Channels (Monaural or Stereo)\n wave[22] = CHANNEL;\n wave[23] = 0;\n\n // fmt chunk -> Sample rate\n wave[24] = (RATE >> 0) & 0xFF;\n wave[25] = (RATE >> 8) & 0xFF;\n wave[26] = (RATE >> 16) & 0xFF;\n wave[27] = (RATE >> 24) & 0xFF;\n\n // fmt chunk -> Byte per second\n wave[28] = (BPS >> 0) & 0xFF;\n wave[29] = (BPS >> 8) & 0xFF;\n wave[30] = (BPS >> 16) & 0xFF;\n wave[31] = (BPS >> 24) & 0xFF;\n\n // fmt chunk -> Block size\n wave[32] = CHANNEL * (QBIT / 8);\n wave[33] = 0;\n\n // fmt chunk -> Byte per Sample\n wave[34] = QBIT;\n wave[35] = 0;\n\n // data chunk\n wave[36] = 0x64; // 'd'\n wave[37] = 0x61; // 'a'\n wave[38] = 0x74; // 't\n wave[39] = 0x61; // 'a'\n\n wave[40] = (DATA_SIZE >> 0) & 0xFF;\n wave[41] = (DATA_SIZE >> 8) & 0xFF;\n wave[42] = (DATA_SIZE >> 16) & 0xFF;\n wave[43] = (DATA_SIZE >> 24) & 0xFF;\n\n for (let i = 0; i < SIZE; i++) {\n switch (QBIT) {\n case 8:\n wave[(RIFF_CHUNK - DATA_SIZE) + i] = sounds[i];\n break;\n case 16:\n // The byte order in WAVE file is little endian\n wave[(RIFF_CHUNK - DATA_SIZE) + (2 * i) + 0] = ((sounds[i] >> 0) & 0xFF);\n wave[(RIFF_CHUNK - DATA_SIZE) + (2 * i) + 1] = ((sounds[i] >> 8) & 0xFF);\n break;\n default:\n break;\n }\n }\n\n // Create WAVE file (Object URL or Data URL)\n const t = String(type).toLowerCase();\n\n switch (t) {\n case 'base64' :\n case 'dataurl':\n const base64 = window.btoa(wave.map(d => String.fromCodePoint(d)).join(''));\n\n if (t === 'base64') {\n return base64;\n }\n\n return `data:audio/wav;base64,${base64}`;\n case 'blob' :\n case 'objecturl':\n default :\n const blob = new Blob([wave], { 'type' : 'audio/wav' });\n\n if (t === 'blob') {\n return blob;\n }\n\n return window.URL.createObjectURL(blob);\n }\n }\n\n /** @override */\n get INPUT() {\n return this.processor;\n }\n\n /** @override */\n get OUTPUT() {\n return this.processor;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Recorder]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../interfaces/Connectable';\n\n/**\n * This private class defines properties for sound session on network.\n * @constructor\n */\nexport class Session extends Connectable {\n static BUFFER_SIZE = 2048;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @param {number} numberOfInputs This argument is the number of inputs for `ScriptProcessorNode`.\n * @param {number} numberOfOutputs This argument the number of outputs for `ScriptProcessorNode`.\n * @param {Analyser} analyser This argument is the instance of `Analyser`.\n */\n constructor(context, bufferSize, numberOfInputs, numberOfOutputs, analyser) {\n super();\n\n this.isActive = false;\n\n this.context = context;\n this.analyser = analyser; // the instance of `Analyser`\n\n // HACK: Fix buffer size on different environments\n this.sender = context.createScriptProcessor(Session.BUFFER_SIZE, numberOfInputs, numberOfOutputs);\n this.receiver = context.createScriptProcessor(Session.BUFFER_SIZE, numberOfInputs, numberOfOutputs);\n\n this.websocket = null; // for the instance of `WebSocket`\n this.paused = true; // for preventing from the duplicate `onaudioprocess` event (`start` method)\n }\n\n /**\n * This method creates the instance of `WebSocket` and registers event handlers.\n * @param {boolean} tls This argument is in order to select protocol (either `wss` or `ws`).\n * @param {string} host This argument is server's hostname.\n * @param {number} port This argument is port number for connection.\n * @param {string} path This argument is file that is executed in server side.\n * @param {function} openCallback This argument is invoked as `onopen` event handler in the instance of `WebSocket`.\n * @param {function} closeCallback This argument is invoked as `onclose` event handler in the instance of `WebSocket`.\n * @param {function} errorCallback This argument is invoked as `onerror` event handler in the instance of `WebSocket`.\n * @return {Session} This is returned for method chain.\n */\n setup(tls, host, port, path, openCallback, closeCallback, errorCallback) {\n /*\n if (!navigator.onLine) {\n // Clear\n this.isActive = false;\n this.paused = true;\n this.connect();\n this.websocket = null;\n\n throw new Error('Now Offline.');\n }\n */\n\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('tls' in properties) {\n tls = properties.tls;\n }\n\n if ('host' in properties) {\n host = properties.host;\n }\n\n if ('port' in properties) {\n port = properties.port;\n }\n\n if ('path' in properties) {\n path = properties.path;\n }\n\n if ('open' in properties) {\n openCallback = properties.open;\n }\n\n if ('close' in properties) {\n closeCallback = properties.close;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n }\n\n const scheme = tls ? 'wss://' : 'ws://';\n\n if (path.charAt(0) !== '/') {\n path = `/${path}`;\n }\n\n const p = parseInt(port, 10);\n\n if (isNaN(p) || (p < 0) || (p > 65535)) {\n return this;\n }\n\n this.websocket = new WebSocket(`${scheme}${host}:${p}${path}`);\n this.websocket.binaryType = 'arraybuffer';\n\n this.websocket.onopen = event => {\n if (Object.prototype.toString.call(openCallback) === '[object Function]') {\n openCallback(event);\n }\n };\n\n this.websocket.onclose = event => {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n\n if (Object.prototype.toString.call(closeCallback) === '[object Function]') {\n closeCallback(event);\n }\n };\n\n this.websocket.onerror = event => {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event);\n }\n };\n\n this.websocket.onmessage = event => {\n if (!this.isActive) {\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n return;\n }\n\n if (event.data instanceof ArrayBuffer) {\n const total = event.data.byteLength / Float32Array.BYTES_PER_ELEMENT;\n const length = Math.floor(total / 2);\n const offset = length * Float32Array.BYTES_PER_ELEMENT;\n\n const bufferLs = new Float32Array(event.data, 0, length); // Get Left channel data\n const bufferRs = new Float32Array(event.data, offset, length); // Get Right channel data\n\n // Start drawing sound wave\n this.analyser.start('time');\n this.analyser.start('fft');\n\n this.receiver.onaudioprocess = event => {\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (bufferLs instanceof Float32Array) { outputLs.set(bufferLs); }\n if (bufferRs instanceof Float32Array) { outputRs.set(bufferRs); }\n\n // bufferLs = null;\n // bufferRs = null;\n\n if (!this.isActive || (this.websocket === null)) {\n this.analyser.stop('time');\n this.analyser.stop('fft');\n }\n };\n }\n };\n\n return this;\n }\n\n /**\n * This method connects nodes according to state.\n * @return {Session} This is returned for method chain.\n */\n connect() {\n // Clear connection\n this.receiver.disconnect(0);\n this.sender.disconnect(0);\n\n this.receiver.onaudioprocess = null;\n this.sender.onaudioprocess = null;\n\n if (this.isActive) {\n // ScriptProcessorNode (Input) -> Analyser\n this.receiver.connect(this.analyser.input);\n\n // ScriptProcessorNode (Input) -> AudioDestinationNode (Output)\n this.receiver.connect(this.context.destination);\n } else {\n this.paused = true;\n }\n\n return this;\n }\n\n /**\n * This method sends sound data to server.\n * @return {Session} This is returned for method chain.\n */\n start() {\n if (this.isActive && this.isConnected() && this.paused) {\n this.paused = false;\n\n const bufferSize = this.sender.bufferSize;\n\n this.sender.onaudioprocess = event => {\n if (this.isActive && this.isConnected()) {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n\n const buffer = new Float32Array(2 * bufferSize);\n const offset = parseInt((buffer.length / 2), 10);\n\n for (let i = 0; i < bufferSize; i++) {\n buffer[i] = inputLs[i];\n buffer[offset + i] = inputRs[i];\n }\n\n if (this.websocket.bufferedAmount === 0) {\n this.websocket.send(buffer);\n }\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method closes connection to server and destroys the instance of `WebSocket`.\n * @return {Session} This is returned for method chain.\n */\n close() {\n if (this.websocket instanceof WebSocket) {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n this.websocket.close();\n\n this.websocket = null;\n }\n\n return this;\n }\n\n /**\n * This method determines whether there is the connection to server.\n * @return {boolean} If the connection to server exists, this value is `true`. Otherwise, this value is `false`.\n */\n isConnected() {\n return (this.websocket instanceof WebSocket) && (this.websocket.readyState === WebSocket.OPEN);\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @param {function} stateCallback This argument is invoked when `bufferedAmount` equals to 0.\n * @param {function} waitCallback This argument is invoked until `bufferedAmount` equals to 0.\n * @return {Session} This is returned for method chain.\n */\n state(state, stateCallback, waitCallback) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (Object.prototype.toString.call(waitCallback) === '[object Function]') {\n waitCallback();\n }\n\n const intervalid = window.setInterval(() => {\n if ((this.websocket instanceof WebSocket) && (this.websocket.bufferedAmount !== 0)) {\n return;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n this.connect();\n\n if (Object.prototype.toString.call(stateCallback) === '[object Function]') {\n stateCallback();\n }\n\n window.clearInterval(intervalid);\n }, 10);\n\n return this;\n }\n\n /**\n * This method gets the instance of `WebSocket`.\n * @return {WebSocket}\n */\n get() {\n return this.websocket;\n }\n\n /** @override */\n get INPUT() {\n return this.sender;\n }\n\n /** @override */\n get OUTPUT() {\n return this.sender;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Session]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\n\n/**\n * This private class defines common properties for effector classes.\n * @constructor\n */\nexport class Effector extends Connectable {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super();\n\n this.isActive = true;\n\n this.context = context;\n\n // for connecting external node\n this.input = context.createGain();\n this.output = context.createGain();\n\n // for LFO (Low Frequency Oscillator)\n // LFO changes parameter cyclically\n this.lfo = context.createOscillator();\n this.depth = context.createGain();\n this.rate = this.lfo.frequency;\n this.processor = context.createScriptProcessor(bufferSize, 2, 2);\n\n // for legacy browsers\n this.lfo.start = this.lfo.start || this.lfo.noteOn;\n this.lfo.stop = this.lfo.stop || this.lfo.noteOff;\n\n this.values = {};\n\n this.isStop = true;\n }\n\n /**\n * This abstract method gets or sets parameter.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Effector} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @abstract\n */\n param() {\n return this;\n }\n\n /**\n * This abstract method connects nodes according to state.\n * @return {Effector} This is returned for method chain.\n * @abstract\n */\n connect() {\n return this;\n }\n\n /**\n * This method starts LFO. Namely, this method starts effector.\n * @param {number} startTime This argument is in order to schedule parameter.\n * @return {Effector} This is returned for method chain.\n */\n start(startTime) {\n if (this.isActive && this.isStop) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.lfo.start(s);\n this.isStop = false;\n }\n\n return this;\n }\n\n /**\n * This method stops LFO, and creates the instance of `OscillatorNode` again.\n * @param {number} stopTime This argument is in order to schedule parameter.\n * @param {number} releaseTime This argument is in order to schedule parameter when it is necessary to consider release time.\n * @return {Effector} This is returned for method chain.\n */\n stop(stopTime, releaseTime) {\n if (this.isActive && !this.isStop) {\n let s = parseFloat(stopTime);\n let r = parseFloat(releaseTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n if (isNaN(r) || (r < 0)) {\n r = 0;\n }\n\n // for saving value\n const type = this.lfo.type;\n const rate = this.lfo.frequency.value;\n\n // Destroy the instance of `OscillatorNode`\n this.lfo.stop(s + r);\n\n // Create the instance of `OscillatorNode` again\n this.lfo = this.context.createOscillator();\n\n // for legacy browsers\n this.lfo.start = this.lfo.start || this.lfo.noteOn;\n this.lfo.stop = this.lfo.stop || this.lfo.noteOff;\n\n // Set the saved value\n this.lfo.type = type;\n this.lfo.frequency.value = rate;\n\n this.rate = this.lfo.frequency;\n\n this.isStop = true;\n }\n\n return this;\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Effector} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n // Start LFO\n this.start(this.context.currentTime);\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n * @abstract\n */\n params() {\n return {};\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n * @abstract\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n get INPUT() {\n return this.input;\n }\n\n /** @override */\n get OUTPUT() {\n return this.output;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Effector]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Autopanner extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.panner = context.createStereoPanner();\n\n // Initialize parameters\n this.panner.pan.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Autopanner` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (pan)\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.panner.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> StereoPannerNode -> GainNode (Output)\n this.input.connect(this.panner);\n this.panner.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Autopanner]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class AutopannerFallback extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitudeL = context.createGain();\n this.amplitudeR = context.createGain();\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createChannelMerger(2);\n\n this.amplitudeL.gain.value = 1; // 1 +- depth\n this.amplitudeR.gain.value = 1; // 1 +- depth\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `AutopannerFallback` is not connected by default\n this.state(false);\n\n // LFO\n this.lfoSplitter = context.createChannelSplitter(2);\n\n // OscillatorNode (LFO) -> GainNode (Depth) -> ScriptProcessorNode -> ChannelSplitterNode -> AudioParam (gain) (L) / (R)\n this.lfo.connect(this.depth);\n this.depth.connect(this.processor);\n this.processor.connect(this.lfoSplitter);\n this.lfoSplitter.connect(this.amplitudeL.gain, 0);\n this.lfoSplitter.connect(this.amplitudeR.gain, 1);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitudeL.disconnect(0);\n this.amplitudeR.disconnect(0);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> ChannelSplitterNode -> GainNode (L) / (R) -> ChannelMergerNode -> GainNode (Output)\n this.input.connect(this.splitter);\n this.splitter.connect(this.amplitudeL, 0, 0);\n this.splitter.connect(this.amplitudeR, 1, 0);\n this.amplitudeL.connect(this.merger, 0, 0);\n this.amplitudeR.connect(this.merger, 0, 1);\n this.merger.connect(this.output);\n } else {\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start(startTime) {\n if (this.isActive && this.isStop) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.lfo.start(s);\n this.isStop = false;\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n const inputs = event.inputBuffer.getChannelData(0);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.depth.gain.value !== 0) && (this.rate.value !== 0)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = inputs[i];\n outputRs[i] = -inputs[i];\n }\n } else {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = 0;\n outputRs[i] = 0;\n }\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.processor);\n this.processor.connect(this.lfoSplitter);\n this.lfoSplitter.connect(this.amplitudeL.gain, 0);\n this.lfoSplitter.connect(this.amplitudeR.gain, 1);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule AutopannerFallback]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Chorus extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay();\n this.mix = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Chorus` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (elayTime)\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.delay.delayTime.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.mix.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive) {\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Chorus]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Compressor extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.compressor = context.createDynamicsCompressor();\n\n // Set default value\n this.compressor.threshold.value = -24;\n this.compressor.knee.value = 30;\n this.compressor.ratio.value = 12;\n this.compressor.attack.value = 0.003;\n this.compressor.release.value = 0.25;\n\n // `Compressor` is connected by default\n this.state(true);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n if (k in this.compressor) {\n if (value === undefined) {\n return this.compressor[k].value;\n }\n\n const v = parseFloat(value);\n\n const minValues = {\n 'threshold' : -100,\n 'knee' : 0,\n 'ratio' : 1,\n 'attack' : 0,\n 'release' : 0\n };\n\n const maxValues = {\n 'threshold' : 0,\n 'knee' : 40,\n 'ratio' : 20,\n 'attack' : 1,\n 'release' : 1\n };\n\n const min = minValues[k];\n const max = maxValues[k];\n\n if ((v >= min) && (v <= max)) {\n this.compressor[k].value = v;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.compressor.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n // GainNode (Input) -> DynamicsCompressorNode -> GainNode (Output)\n this.input.connect(this.compressor);\n this.compressor.connect(this.output);\n } else {\n // Effect OFF\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'threshold' : this.compressor.threshold.value,\n 'knee' : this.compressor.knee.value,\n 'ratio' : this.compressor.ratio.value,\n 'attack' : this.compressor.attack.value,\n 'release' : this.compressor.release.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Compressor]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Delay extends Effector {\n static MAX_DELAY_TIME = 5; // Max delay time is 5000 [ms]\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay(Delay.MAX_DELAY_TIME);\n this.dry = context.createGain();\n this.wet = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n\n // `Delay` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = Delay.MAX_DELAY_TIME;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n }\n\n break;\n case 'dry' :\n case 'wet' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Dry) -> GainNode (Output)\n this.input.connect(this.dry);\n this.dry.connect(this.output);\n\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Wet) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.wet);\n this.wet.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'dry' : this.dry.gain.value,\n 'wet' : this.wet.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Delay]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Distortion extends Effector {\n static CLEAN = 'clean';\n static CRUNCH = 'crunch';\n static OVERDRIVE = 'overdrive';\n static DISTORTION = 'distortion';\n static FUZZ = 'fuzz';\n\n /**\n * This class (static) method creates the instance of `Float32Array` for distortion.\n * @param {string} type This argument is one of 'clean', 'crunch', 'overdrive', 'distortion', 'fuzz'.\n * @param {number} amount This argument is the depth of distortion.\n * @param {number} numberOfSamples This argument is the size of `Float32Array`.\n * @return {Float32Array|null} This is `curve` property in `WaveShaperNode`.\n */\n static createCurve(type, amount, numberOfSamples) {\n // This algorithms are from https://github.com/Theodeus/tuna/blob/master/tuna.js#L1301,L1359\n if ((amount > 0) && (amount < 1)) {\n const curves = new Float32Array(numberOfSamples);\n\n let x = 0;\n let y = 0;\n let a = 0;\n let k = 0;\n let abx = 0;\n\n switch (type) {\n case Distortion.CRUNCH:\n a = 1 - amount > 0.99 ? 0.99 : 1 - amount;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n abx = Math.abs(x);\n\n if (abx < a) {\n y = abx;\n } else if (abx > a) {\n y = a + (abx - a) / (1 + Math.pow((abx - a) / (1 - a), 2));\n } else if (abx > 1) {\n y = abx;\n }\n\n curves[i] = (x === 0 ? 1 : Math.abs(x) / x) * y * (1 / ((a + 1) / 2));\n }\n\n /*\n const a = 2 + Math.round(amount * 14);\n const bits = Math.round(Math.pow(2, a - 1));\n\n let x = 0;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n curves[i] = Math.round(x * bits) / bits;\n }\n */\n\n break;\n case Distortion.OVERDRIVE:\n k = (2 * amount) / (1 - amount);\n\n for (let i = 0; i < numberOfSamples; i++) {\n // LINEAR INTERPOLATION: x := (c - a) * (z - y) / (b - a) + y\n // a = 0, b = 2048, z = 1, y = -1, c = i\n const x = (((i - 0) * (1 - (-1))) / (numberOfSamples - 0)) + (-1);\n curves[i] = ((1 + k) * x) / (1 + k * Math.abs(x));\n }\n\n /*\n let x = 0;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n\n if (x < -0.08905) {\n curves[i] = (-3 / 4) * (1 - (Math.pow((1 - (Math.abs(x) - 0.032857)), 12)) + (1 / 3) * (Math.abs(x) - 0.032847)) + 0.01;\n } else if (x >= -0.08905 && x < 0.320018) {\n curves[i] = (-6.153 * (x * x)) + 3.9375 * x;\n } else {\n curves[i] = 0.630035;\n }\n }\n */\n\n break;\n case Distortion.DISTORTION:\n a = 1 - amount;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n y = x < 0 ? -Math.pow(Math.abs(x), a + 0.04) : Math.pow(x, a);\n curves[i] = (Math.exp(2 * y) - Math.exp(-2 * y)) / (Math.exp(2 * y) + Math.exp(-2 * y));\n }\n\n break;\n case Distortion.FUZZ:\n for (let i = 0; i < numberOfSamples; i++) {\n x = ((i * 2) / numberOfSamples) - 1;\n y = ((0.5 * Math.pow((x + 1.4), 2)) - 1) * y >= 0 ? 5.8 : 1.2;\n\n curves[i] = (Math.exp(y) - Math.exp(-y)) / (Math.exp(y) + Math.exp(-y));\n }\n\n break;\n case Distortion.CLEAN:\n default:\n return null;\n }\n\n return curves;\n }\n\n return null; // Clean sound (default value)\n }\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.distortion = context.createWaveShaper();\n this.drive = context.createGain();\n this.color = context.createBiquadFilter();\n this.tone = context.createBiquadFilter();\n\n // Distortion type\n this.type = Distortion.CLEAN;\n\n // for creating curve\n this.amount = 0.5;\n this.numberOfSamples = 4096;\n\n // Initialize parameters\n this.drive.gain.value = 1;\n this.color.type = (typeof this.color.type === 'string') ? 'bandpass' : (this.color.BANDPASS || 2);\n this.color.frequency.value = 350;\n this.color.Q.value = Math.SQRT1_2;\n this.color.gain.value = 0; // Not used\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n\n // `Distortion` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'curve':\n if (value === undefined) {\n return this.distortion.curve;\n }\n\n let curve = null;\n\n switch (String(value).toLowerCase()) {\n case Distortion.CLEAN:\n this.type = Distortion.CLEAN;\n curve = Distortion.createCurve(Distortion.CLEAN, this.amount, this.numberOfSamples);\n break;\n case Distortion.CRUNCH:\n this.type = Distortion.CRUNCH;\n curve = Distortion.createCurve(Distortion.CRUNCH, this.amount, this.numberOfSamples);\n break;\n case Distortion.OVERDRIVE:\n this.type = Distortion.OVERDRIVE;\n curve = Distortion.createCurve(Distortion.OVERDRIVE, this.amount, this.numberOfSamples);\n break;\n case Distortion.DISTORTION:\n this.type = Distortion.DISTORTION;\n curve = Distortion.createCurve(Distortion.DISTORTION, this.amount, this.numberOfSamples);\n break;\n case Distortion.FUZZ:\n this.type = Distortion.FUZZ;\n curve = Distortion.createCurve(Distortion.FUZZ, this.amount, this.numberOfSamples);\n break;\n default:\n if (value instanceof Float32Array) {\n curve = value;\n }\n\n break;\n }\n\n this.distortion.curve = curve;\n\n break;\n case 'amount':\n if (value === undefined) {\n return this.amount;\n }\n\n v = parseFloat(value);\n\n if ((v > 0) && (v < 1)) {\n this.amount = v;\n this.param('curve', this.type);\n }\n\n break;\n case 'samples':\n if (value === undefined) {\n return this.numberOfSamples;\n }\n\n v = parseInt(value, 10);\n\n if (v >= 0) {\n this.numberOfSamples = v;\n this.param('curve', this.type);\n }\n\n break;\n case 'drive':\n if (value === undefined) {\n return this.drive.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 100;\n\n if ((v >= min) && (v <= max)) {\n this.drive.gain.value = v;\n }\n\n break;\n case 'color':\n case 'tone' :\n if (value === undefined) {\n return this[k].frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this[k].frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.color.disconnect(0);\n this.drive.disconnect(0);\n this.distortion.disconnect(0);\n this.tone.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Color) -> WaveShaperNode (Distortion) -> GainNode (Drive) -> BiquadFilterNode (Tone) -> GainNode (Output)\n this.input.connect(this.color);\n this.color.connect(this.drive);\n this.drive.connect(this.distortion);\n this.distortion.connect(this.tone);\n this.tone.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'curve' : this.type,\n 'amount' : this.amount,\n 'samples' : this.numberOfSamples,\n 'drive' : this.drive.gain.value,\n 'color' : this.color.frequency.value,\n 'tone' : this.tone.frequency.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Distortion]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Envelope Generator.\n * @constructor\n */\nexport class EnvelopeGenerator {\n static MIN_GAIN = 1e-3;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n /** @type {Array.<GainNode>} */\n this.generators = [];\n\n // for `GainNode`\n this.activeIndexes = [];\n this.activeCounter = 0;\n\n this.attack = 0.01;\n this.decay = 0.3;\n this.sustain = 0.5;\n this.release = 1.0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|EnvelopeGenerator} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'attack' :\n case 'sustain':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this[k] = v;\n }\n\n break;\n case 'decay' :\n case 'release':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method connects the instance of `AudioNode`.\n * @param {number} index This argument is in order to select the instance of `GainNode` that is Envelope Generator.\n * @param {AudioNode} input This argument is the instance of `AudioNode` as input.\n * @param {AudioNode} output This argument is the instance of `AudioNode` as output.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n ready(index, input, output) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n if ((input instanceof AudioNode) && (output instanceof AudioNode)) {\n input.connect(this.generators[i]);\n this.generators[i].connect(output);\n } else if (input instanceof AudioNode) {\n input.connect(this.generators[i]);\n } else if (output instanceof AudioNode) {\n this.generators[i].connect(output);\n }\n\n this.activeIndexes[i] = i;\n this.activeCounter++;\n\n return this;\n }\n\n /**\n * This method changes gain (Attack -> Decay -> Sustain).\n * @param {number} startTime This argument is the start time of Attack.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n start(startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n // Attack -> Decay -> Sustain\n const t0 = s;\n const t1 = t0 + this.attack;\n const t2 = this.decay;\n const t2Value = this.sustain;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n // Start from `gain.value = 0`\n this.generators[activeIndex].gain.cancelScheduledValues(t0);\n this.generators[activeIndex].gain.setValueAtTime(0, t0);\n\n // Attack : `gain.value` increases linearly until assigned time (t1)\n this.generators[activeIndex].gain.linearRampToValueAtTime(1, t1);\n\n // Decay -> Sustain : `gain.value` gradually decreases to value of Sustain during of Decay time (t2) from assigned time (t1)\n this.generators[activeIndex].gain.setTargetAtTime(t2Value, t1, t2);\n }\n\n return this;\n }\n\n /**\n * This method changes gain (Attack or Decay or Sustain -> Release).\n * @param {number} stopTime This argument is the start time of Release.\n * @param {boolean} useCurve This argument is to use different methods.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n stop(stopTime, useCurve) {\n let s = parseFloat(stopTime) - this.release;\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n // Sustain -> Release\n const t3 = s;\n const t4 = this.release;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n // in the case of mouseup on the way of Decay\n this.generators[activeIndex].gain.cancelScheduledValues(t3);\n\n // Release : `gain.value` gradually decreases to 0 during of Release time (t4) from assigned time (t3)\n // NOTE: https://www.w3.org/TR/webaudio/#dom-audioparam-settargetattime\n if (useCurve) {\n this.generators[activeIndex].gain.setValueCurveAtTime(new Float32Array([1, 0.5, 0.25, 0]), t3, t4);\n } else {\n this.generators[activeIndex].gain.setTargetAtTime(0, t3, t4);\n }\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is the index of array that contains the instance of `GainNode` for Envelope Generator.\n * @return {GainNode} This is returned as the instance of `GainNode` for Envelope Generator.\n */\n getGenerator(index) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n return this.generators[i];\n }\n\n /**\n * This method sets the instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is the index of array that contains the instance of `GainNode` for Envelope Generator.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n setGenerator(index) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n this.generators[i] = this.context.createGain();\n\n // for legacy browsers\n this.generators[i].gain.setTargetAtTime = this.generators[i].gain.setTargetAtTime || this.generators[i].gain.setTargetValueAtTime;\n\n return this;\n }\n\n /**\n * This method determines whether the all of gain schedulings have ended.\n * @return {boolean} If the all of gain schedulings have ended, this value is `true`. Otherwise, this value is `false`.\n */\n isStop() {\n let counter = 0;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n if (this.generators[activeIndex].gain.value > EnvelopeGenerator.MIN_GAIN) {\n return false;\n }\n\n counter++;\n\n // the all of schedulings are stopped ?\n if (counter === this.activeCounter) {\n return true;\n }\n }\n }\n\n /**\n * This method clears variables for managing the instance of `GainNode`.\n * @param {boolean} isDisconnect This argument is in order to determine whether disconnect `AudioNode`.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n clear(isDisconnect) {\n this.activeIndexes.length = 0;\n this.activeCounter = 0;\n\n for (const generator of this.generators) {\n generator.gain.cancelScheduledValues(this.context.currentTime);\n generator.gain.value = 1;\n\n if (isDisconnect) {\n generator.disconnect(0);\n }\n }\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {\n 'attack' : this.attack,\n 'decay' : this.decay,\n 'sustain' : this.sustain,\n 'release' : this.release\n };\n\n return params;\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule EnvelopeGenerator]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Equalizer extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n **/\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n this.presence = context.createBiquadFilter();\n\n // Set filter type\n this.bass.type = (typeof this.bass.type === 'string') ? 'lowshelf' : (this.bass.LOWSHELF || 3);\n this.middle.type = (typeof this.middle.type === 'string') ? 'peaking' : (this.middle.PEAKING || 5);\n this.treble.type = (typeof this.treble.type === 'string') ? 'peaking' : (this.treble.PEAKING || 5);\n this.presence.type = (typeof this.presence.type === 'string') ? 'highshelf' : (this.presence.HIGHSHELF || 4);\n\n // Set cutoff frequency\n this.bass.frequency.value = 500; // 500 Hz\n this.middle.frequency.value = 1000; // 1 kHz\n this.treble.frequency.value = 2000; // 2 kHz\n this.presence.frequency.value = 4000; // 4 kHz\n\n // Set Q\n // this.bass.Q.value = Math.SQRT1_2; // Not used\n this.middle.Q.value = Math.SQRT1_2;\n this.treble.Q.value = Math.SQRT1_2;\n // this.presence.Q.value = Math.SQRT1_2; // Not used\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n this.presence.gain.value = 0;\n\n // `Equalizer` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'bass' :\n case 'middle' :\n case 'treble' :\n case 'presence':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = -40;\n max = 40;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.bass.disconnect(0);\n this.middle.disconnect(0);\n this.treble.disconnect(0);\n this.presence.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Bass) -> BiquadFilterNode (Middle) -> BiquadFilterNode (Treble) -> BiquadFilterNode (Presence) -> GainNode (Output)\n this.input.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.connect(this.presence);\n this.presence.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'bass' : this.bass.gain.value,\n 'middle' : this.middle.gain.value,\n 'treble' : this.treble.gain.value,\n 'presence' : this.presence.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Equalizer]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Filter extends Effector {\n // for legacy browsers\n static FILTER_TYPES = {\n 'lowpass' : 0,\n 'highpass' : 1,\n 'bandpass' : 2,\n 'lowshelf' : 3,\n 'highshelf' : 4,\n 'peaking' : 5,\n 'notch' : 6,\n 'allpass' : 7\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.filter = context.createBiquadFilter();\n\n // for legacy browsers\n this.filter.frequency.setTargetAtTime = this.filter.frequency.setTargetAtTime || this.filter.frequency.setTargetValueAtTime;\n\n // Initialize parameters\n this.filter.type = (typeof this.filter.type === 'string') ? 'lowpass' : (this.filter.LOWPASS || 0);\n this.filter.frequency.value = 350;\n this.filter.Q.value = 1;\n this.filter.gain.value = 0;\n\n this.maxFrequency = this.filter.frequency.value;\n this.range = 0.1; // 10% -> between `this.maxFrequency * 0.1` and `this.maxFrequency`\n\n this.attack = 0.01;\n this.decay = 0.3;\n this.sustain = 1.0;\n this.release = 1.0;\n\n // `Filter` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.filter.type;\n }\n\n v = String(value).toLowerCase();\n\n if (v in Filter.FILTER_TYPES) {\n this.filter.type = (typeof this.filter.type === 'string') ? v : Filter.FILTER_TYPES[v];\n }\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.filter.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.maxFrequency = v;\n this.filter.frequency.value = v;\n }\n\n break;\n case 'gain':\n if (value === undefined) {\n return this.filter.gain.value;\n }\n\n v = parseFloat(value);\n min = -40;\n max = 40;\n\n if ((v >= min) && (v <= max)) {\n this.filter.gain.value = v;\n }\n\n break;\n case 'q':\n if (value === undefined) {\n return this.filter.Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n this.filter.Q.value = v;\n }\n\n break;\n case 'range':\n if (value === undefined) {\n return this.range;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.range = v;\n }\n\n break;\n case 'attack' :\n case 'sustain':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this[k] = v;\n }\n\n break;\n case 'decay' :\n case 'release':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.filter.disconnect(0);\n\n if (this.isActive) {\n // Effector ON\n\n // GainNode (Input) -> BiquadFilterNode -> GainNode (Output)\n this.input.connect(this.filter);\n this.filter.connect(this.output);\n } else {\n // Effector OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start(startTime) {\n if (this.isActive) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t0 = s;\n const t1 = t0 + this.attack;\n const t2 = this.decay;\n const t2Value = this.sustain * this.maxFrequency;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n this.filter.frequency.cancelScheduledValues(t0);\n this.filter.frequency.setValueAtTime(minFrequnecy, t0);\n this.filter.frequency.linearRampToValueAtTime(this.maxFrequency, t1); // Attack\n this.filter.frequency.setTargetAtTime(t2Value, t1, t2); // Decay -> Sustain\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime) {\n if (this.isActive) {\n let s = parseFloat(stopTime) - this.release;\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t3 = s;\n const t4 = this.release;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n this.filter.frequency.cancelScheduledValues(t3);\n this.filter.frequency.setValueAtTime(this.filter.frequency.value, t3);\n this.filter.frequency.setTargetAtTime(minFrequnecy, t3, t4); // Sustain -> Release\n }\n\n return this;\n }\n\n /** @override */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'type' : this.filter.type,\n 'frequency' : this.filter.frequency.value,\n 'Q' : this.filter.Q.value,\n 'gain' : this.filter.gain.value,\n 'range' : this.range,\n 'attack' : this.attack,\n 'decay' : this.decay,\n 'sustain' : this.sustain,\n 'release' : this.release\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Filter]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Flanger extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay();\n this.mix = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Flanger` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (delayTime)\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.delay.delayTime.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.mix.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive) {\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Flanger]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Listener extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n // the instance of `AudioListener`\n this.listener = context.listener;\n\n // Set default value\n this.positions = { 'x' : 0, 'y' : 0, 'z' : 0 };\n this.forwards = { 'x' : 0, 'y' : 0, 'z' : -1 };\n this.ups = { 'x' : 0, 'y' : 1, 'z' : 0 };\n\n if ((this.listener.positionX instanceof AudioParam) && (this.listener.positionY instanceof AudioParam) && (this.listener.positionZ instanceof AudioParam)) {\n this.listener.positionX.setValueAtTime(this.positions.x, context.currentTime);\n this.listener.positionY.setValueAtTime(this.positions.y, context.currentTime);\n this.listener.positionZ.setValueAtTime(this.positions.z, context.currentTime);\n } else {\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Listener} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'x':\n case 'y':\n case 'z':\n if (value === undefined) {\n return this.positions[k];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.positions[k] = v;\n\n if ((this.listener.positionX instanceof AudioParam) && (this.listener.positionY instanceof AudioParam) && (this.listener.positionZ instanceof AudioParam)) {\n this.listener.positionX.setValueAtTime(this.positions.x, this.context.currentTime);\n this.listener.positionY.setValueAtTime(this.positions.y, this.context.currentTime);\n this.listener.positionZ.setValueAtTime(this.positions.z, this.context.currentTime);\n } else {\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n }\n\n break;\n case 'fx':\n case 'fy':\n case 'fz':\n if (value === undefined) {\n return this.forwards[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.forwards[k.charAt(1)] = v;\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, this.context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, this.context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, this.context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, this.context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n break;\n case 'ux':\n case 'uy':\n case 'uz':\n if (value === undefined) {\n return this.ups[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.ups[k.charAt(1)] = v;\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, this.context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, this.context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, this.context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, this.context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {\n 'state' : this.isActive,\n 'positions' : this.positions,\n 'forwards' : this.forwards,\n 'ups' : this.ups\n };\n\n return params;\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule Listener]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Panner extends Effector {\n static PANNING_MODELS = {\n 'equalpower' : 0,\n 'HRTF' : 1\n };\n\n static DISTANCE_MODELS = {\n 'linear' : 0,\n 'inverse' : 1,\n 'exponential' : 2\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.panner = context.createPanner();\n\n this.positions = { 'x' : 0, 'y' : 0, 'z' : 0 };\n this.orientations = { 'x' : 1, 'y' : 0, 'z' : 0 };\n\n this.panner.refDistance = 1;\n this.panner.maxDistance = 10000;\n this.panner.rolloffFactor = 1;\n\n this.panner.coneInnerAngle = 360;\n this.panner.coneOuterAngle = 360;\n this.panner.coneOuterGain = 0;\n\n this.panner.panningModel = (typeof this.panner.panningModel === 'string') ? 'HRTF' : (this.panner.HRTF || 1);\n this.panner.distanceModel = (typeof this.panner.distanceModel === 'string') ? 'inverse' : (this.panner.INVERSE_DISTANCE || 1);\n\n if ((this.panner.positionX instanceof AudioParam) && (this.panner.positionY instanceof AudioParam) && (this.panner.positionZ instanceof AudioParam)) {\n this.panner.positionX.setValueAtTime(this.positions.x, context.currentTime);\n this.panner.positionY.setValueAtTime(this.positions.y, context.currentTime);\n this.panner.positionZ.setValueAtTime(this.positions.z, context.currentTime);\n } else {\n this.panner.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n if ((this.panner.orientationX instanceof AudioParam) && (this.panner.orientationY instanceof AudioParam) && (this.panner.orientationZ instanceof AudioParam)) {\n this.panner.orientationX.setValueAtTime(this.orientations.x, context.currentTime);\n this.panner.orientationY.setValueAtTime(this.orientations.y, context.currentTime);\n this.panner.orientationZ.setValueAtTime(this.orientations.z, context.currentTime);\n } else {\n this.panner.setOrientation(this.orientations.x, this.orientations.y, this.orientations.z);\n }\n\n // `Panner` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'x':\n case 'y':\n case 'z':\n if (value === undefined) {\n return this.positions[k];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.positions[k] = v;\n\n if ((this.panner.positionX instanceof AudioParam) && (this.panner.positionY instanceof AudioParam) && (this.panner.positionZ instanceof AudioParam)) {\n this.panner.positionX.setValueAtTime(this.positions.x, this.context.currentTime);\n this.panner.positionY.setValueAtTime(this.positions.y, this.context.currentTime);\n this.panner.positionZ.setValueAtTime(this.positions.z, this.context.currentTime);\n } else {\n this.panner.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n }\n\n break;\n case 'ox':\n case 'oy':\n case 'oz':\n if (value === undefined) {\n return this.orientations[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.orientations[k.charAt(1)] = v;\n\n if ((this.panner.orientationX instanceof AudioParam) && (this.panner.orientationY instanceof AudioParam) && (this.panner.orientationZ instanceof AudioParam)) {\n this.panner.orientationX.setValueAtTime(this.orientations.x, this.context.currentTime);\n this.panner.orientationY.setValueAtTime(this.orientations.y, this.context.currentTime);\n this.panner.orientationZ.setValueAtTime(this.orientations.z, this.context.currentTime);\n } else {\n this.panner.setOrientation(this.orientations.x, this.orientations.y, this.orientations.z);\n }\n }\n\n break;\n case 'refdistance':\n if (value === undefined) {\n return this.panner.refDistance;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.panner.refDistance = v;\n }\n\n break;\n case 'maxdistance':\n if (value === undefined) {\n return this.panner.maxDistance;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.panner.maxDistance = v;\n }\n\n break;\n case 'rollofffactor':\n if (value === undefined) {\n return this.panner.rolloffFactor;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.panner.rolloffFactor = v;\n }\n\n break;\n case 'coneinnerangle':\n if (value === undefined) {\n return this.panner.coneInnerAngle;\n }\n\n v = parseFloat(value);\n\n if ((v >= 0) && (v <= 360)) {\n this.panner.coneInnerAngle = v;\n }\n\n break;\n case 'coneouterangle':\n if (value === undefined) {\n return this.panner.coneOuterAngle;\n }\n\n v = parseFloat(value);\n\n if ((v >= 0) && (v <= 360)) {\n this.panner.coneOuterAngle = v;\n }\n\n break;\n case 'coneoutergain':\n if ((v >= 0) && (v <= 1)) {\n return this.panner.coneOuterGain;\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.panner.coneOuterGain = v;\n }\n\n break;\n case 'panningmodel':\n if (value === undefined) {\n return this.panner.panningModel;\n }\n\n v = /HRTF/i.test(value) ? String(value).toUpperCase() : String(value).toLowerCase();\n\n if (v in Panner.PANNING_MODELS) {\n this.panner.panningModel = (typeof this.panner.panningModel === 'string') ? v : Panner.PANNING_MODELS[v];\n }\n\n break;\n case 'distancemodel':\n if (value === undefined) {\n return this.panner.distanceModel;\n }\n\n v = String(value).replace(/-/g, '').toLowerCase();\n\n if (v in Panner.DISTANCE_MODELS) {\n this.panner.distanceModel = (typeof this.panner.distanceModel === 'string') ? v : Panner.DISTANCE_MODELS[v];\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.panner.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> PannerNode -> GainNode (Output)\n this.input.connect(this.panner);\n this.panner.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'positions' : this.positions,\n 'orientations' : this.orientations,\n 'refDistance' : this.panner.refDistance,\n 'maxDistance' : this.panner.maxDistance,\n 'rolloffFactor' : this.panner.rolloffFactor,\n 'coneInnerAngle' : this.panner.coneInnerAngle,\n 'coneOuterAngle' : this.panner.coneOuterAngle,\n 'coneOuterGain' : this.panner.coneOuterGain,\n 'panningModel' : this.panner.panningModel,\n 'distanceModel' : this.panner.distanceModel\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Panner]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Phaser extends Effector {\n static MAXIMUM_STAGES = 24; // The maximum number of All-Pass Filters\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.numberOfStages = 12; // The default number of All-Pass Filters\n this.filters = new Array(Phaser.MAXIMUM_STAGES);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i] = context.createBiquadFilter();\n this.filters[i].type = (typeof this.filters[i].type === 'string') ? 'allpass' : (this.filters[i].ALLPASS || 7);\n this.filters[i].frequency.value = 350;\n this.filters[i].Q.value = 1;\n this.filters[i].gain.value = 0; // Not used\n }\n\n this.mix = context.createGain();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Phaser` is not connected by default\n this.state(false);\n\n // LFO\n // GainNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'stage':\n if (value === undefined) {\n return this.numberOfStages;\n }\n\n v = parseInt(value, 10);\n\n switch (v) {\n case 0:\n case 2:\n case 4:\n case 8:\n case 12:\n case 24:\n this.numberOfStages = v;\n this.connect();\n break;\n default:\n break;\n }\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.filters[0].frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i].frequency.value = v;\n }\n\n this.depth.gain.value = this.filters[0].frequency.value * this.depthRate;\n }\n\n break;\n case 'resonance':\n if (value === undefined) {\n return this.filters[0].Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[0].Q.value = v;\n }\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.filters[0].frequency.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i].disconnect(0);\n }\n\n this.mix.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive && (this.numberOfStages > 0)) {\n // GainNode (Input) -> BiquadFilterNode (All-Pass Filter x N) -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.filters[0]);\n\n for (let i = 0; i < this.numberOfStages; i++) {\n if (i < (this.numberOfStages - 1)) {\n this.filters[i].connect(this.filters[i + 1]);\n } else {\n this.filters[i].connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> BiquadFilterNode (All-Pass Filter x N) -> GainNode (Feedback) -> BiquadFilterNode (All-Pass Filter x N) ...\n this.filters[i].connect(this.feedback);\n this.feedback.connect(this.filters[0]);\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'stage' : this.numberOfStages,\n 'frequency' : this.filters[0].frequency.value,\n 'resonance' : this.filters[0].Q.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Phaser]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class PitchShifter extends Effector {\n /**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\n static FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n }\n\n /**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\n static IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n }\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.pitch = 1;\n\n // `PitchShifter` is not connected by default\n this.state(false);\n\n this.connect();\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n\n switch (k) {\n case 'pitch':\n if (value === undefined) {\n return this.pitch;\n }\n\n v = parseFloat(value);\n min = 0;\n\n if (v > min) {\n this.pitch = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> ScriptProcessorNode -> GainNode (Output);\n this.input.connect(this.processor);\n this.processor.connect(this.output);\n } else {\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start() {\n if (this.isActive && this.isStop) {\n this.isStop = false;\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.pitch !== 1)) {\n const realLs = new Float32Array(inputLs);\n const realRs = new Float32Array(inputRs);\n const imagLs = new Float32Array(bufferSize);\n const imagRs = new Float32Array(bufferSize);\n\n PitchShifter.FFT(realLs, imagLs, bufferSize);\n PitchShifter.FFT(realRs, imagRs, bufferSize);\n\n const arealLs = new Float32Array(bufferSize);\n const arealRs = new Float32Array(bufferSize);\n const aimagLs = new Float32Array(bufferSize);\n const aimagRs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n const offset = Math.floor(this.pitch * i);\n\n let eq = 1;\n\n if (i > (bufferSize / 2)) {\n eq = 0;\n }\n\n if ((offset >= 0) && (offset < bufferSize)) {\n arealLs[offset] += eq * realLs[i];\n aimagLs[offset] += eq * imagLs[i];\n arealRs[offset] += eq * realRs[i];\n aimagRs[offset] += eq * imagRs[i];\n }\n }\n\n PitchShifter.IFFT(arealLs, aimagLs, bufferSize);\n PitchShifter.IFFT(arealRs, aimagRs, bufferSize);\n\n outputLs.set(arealLs);\n outputRs.set(arealRs);\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop() {\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // Connect nodes again\n this.connect();\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'pitch' : this.pitch\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule PitchShifter]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Reverb extends Effector {\n static ERROR_AJAX = 'error';\n static ERROR_AJAX_TIMEOUT = 'timeout';\n static ERROR_DECODE = 'decode';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n // If the error is at least 1, this method aborts the all of connections.\n // Therefore, this flag are shared with the all instances of `XMLHttpRequest`.\n this.isLoadError = false;\n\n this.rirs = [];\n this.convolver = context.createConvolver();\n this.dry = context.createGain();\n this.wet = context.createGain();\n this.tone = context.createBiquadFilter();\n\n // Initialize parameters\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n\n // `Reverb` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.convolver.buffer;\n }\n\n v = parseInt(value, 10);\n min = 0;\n max = this.rirs.length - 1;\n\n if (value === null) {\n this.convolver.buffer = null;\n\n // If `buffer` in `ConvolverNode` is `null` after setting the instance of `AudioBuffer`, `Reverb` is not OFF.\n // Therefore, `Reverb` is OFF by disconnecting nodes.\n this.input.disconnect(0);\n this.input.connect(this.output);\n } else if ((v >= min) && (v <= max)) {\n this.convolver.buffer = this.rirs[v];\n this.connect();\n }\n\n break;\n case 'dry':\n case 'wet':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n case 'rirs':\n return this.rirs; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.convolver.disconnect(0);\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n this.tone.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Dry) -> GainNode (Output)\n this.input.connect(this.dry);\n this.dry.connect(this.output);\n\n // GainNode (Input) -> BiquadFilterNode (Tone) -> ConvolverNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.convolver);\n this.convolver.connect(this.wet);\n this.wet.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /**\n * This method sets instance of `AudioBuffer` to `ConvolverNode`.\n * @param {AudioBuffer|ArrayBuffer} impulse This argument is in order to convolve impulse response.\n * This argument is the instance of `AudioBuffer` or `ArrayBuffer` for impulse response.\n * @param {function} errorCallback This argument is in order to be invoked when error occurs.\n * @return {Reverb} This is returned for method chain.\n * @override\n */\n start(impulse, errorCallback) {\n if ((impulse instanceof AudioBuffer) || (impulse === null)) {\n this.convolver.buffer = impulse;\n this.rirs.push(impulse); // Add to preset\n } else if (impulse instanceof ArrayBuffer) {\n const successCallback = buffer => {\n this.convolver.buffer = buffer;\n this.rirs.push(buffer); // Add to preset\n };\n\n if (Object.prototype.toString.call(errorCallback) !== '[object Function]') {\n errorCallback = () => {};\n }\n\n this.context.decodeAudioData(impulse, successCallback, errorCallback);\n }\n\n return this;\n }\n\n /**\n * This method creates the instances of `AudioBuffer` by Ajax for Revreb presets.\n * @param {Array.<string>|Array.<AudioBuffer>} rirs This argument is either URLs or the instances of `AudioBuffer` for impulse response.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked when the creating the instances of `AudioBuffer` was completed.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {Reverb} This is returned for method chain.\n */\n preset(rirs, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('rirs' in properties) {\n rirs = properties.rirs;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!Array.isArray(rirs)) {\n rirs = [rirs];\n }\n\n this.rirs = new Array(rirs.length);\n\n const t = parseInt(timeout, 10);\n\n for (let i = 0, len = rirs.length; i < len; i++) {\n if (typeof rirs[i] === 'string') {\n // Get the instances of `AudioBuffer` from the designated URLs.\n this.load(rirs[i], i, t, successCallback, errorCallback, progressCallback);\n } else if (rirs[i] instanceof AudioBuffer) {\n // Get the instances of `AudioBuffer` directly\n this.rirs[i] = rirs[i];\n }\n }\n\n return this;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates the instances of `AudioBuffer`.\n * @param {string} url This argument is resource URL for one-shot audio.\n * @param {number} index This argument is in order to assign the instance of `AudioBuffer`.\n * @param {number} timeout This argument is Ajax timeout.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {Reverb} This is returned for method chain.\n */\n load(url, index, timeout, successCallback, errorCallback, progressCallback) {\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = (timeout > 0) ? timeout : 60000;\n\n xhr.ontimeout = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, Reverb.ERROR_AJAX_TIMEOUT);\n }\n\n this.isLoadError = true;\n };\n\n xhr.onprogress = event => {\n if (this.isLoadError) {\n xhr.abort();\n } else if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, Reverb.ERROR_AJAX);\n }\n\n this.isLoadError = true;\n };\n\n // Success\n xhr.onload = event => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = audioBuffer => {\n this.rirs[index] = audioBuffer;\n\n // The creating the instances of `AudioBuffer` has completed ?\n for (const rir of this.rirs) {\n if (rir === undefined) {\n return;\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(event);\n }\n };\n\n const decodeErrorCallback = error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error, Reverb.ERROR_DECODE);\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n\n return this;\n }\n\n /** @override */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'dry' : this.dry.gain.value,\n 'wet' : this.wet.gain.value,\n 'tone' : this.tone.frequency.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Reverb]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Ringmodulator extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitude = context.createGain();\n\n this.amplitude.gain.value = 0; // 0 +- depth\n\n // Initialize parameter\n this.depth.gain.value = 1;\n this.rate.value = 0;\n\n // `Ringmodulator` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (gain)\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitude.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode -> GainNode (Output)\n this.input.connect(this.amplitude);\n this.amplitude.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Ringmodulator]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Stereo extends Effector {\n static MAX_DELAY_TIME = 1; // Max delay time is 1000 [ms]\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createScriptProcessor(bufferSize, 2, 2);\n this.delayL = context.createDelay(Stereo.MAX_DELAY_TIME);\n this.delayR = context.createDelay(Stereo.MAX_DELAY_TIME);\n\n // Initialize parameters\n this.delayL.delayTime.value = 0;\n this.delayR.delayTime.value = 0;\n\n // `Stereo` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delayL.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = Stereo.MAX_DELAY_TIME;\n\n if ((v >= min) && (v <= max)) {\n this.delayL.delayTime.value = v;\n this.delayR.delayTime.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.splitter.disconnect(0);\n this.delayL.disconnect(0);\n this.delayR.disconnect(0);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> ChannelSplitterNode -> DelayNode (L) / (R) -> ScriptProcessorNode -> GainNode (Output)\n this.input.connect(this.splitter);\n this.splitter.connect(this.delayL, 0, 0);\n this.splitter.connect(this.delayR, 1, 0);\n this.delayL.connect(this.merger);\n this.delayR.connect(this.merger);\n this.merger.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start() {\n if (this.isActive && this.isStop) {\n this.isStop = false;\n\n const bufferSize = this.merger.bufferSize;\n\n this.merger.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.delayL.delayTime.value !== 0) && (this.delayR.delayTime.value !== 0)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = inputLs[i];\n outputRs[i] = -inputRs[i];\n }\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop() {\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.merger.disconnect(0);\n this.merger.onaudioprocess = null;\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delayL.delayTime.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Stereo]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Tremolo extends Effector {\n // for legacy browsers\n static WAVE_TYPES = {\n 'sine' : 0,\n 'square' : 1,\n 'sawtooth' : 2,\n 'triangle' : 3\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitude = context.createGain();\n\n this.amplitude.gain.value = 1; // 1 +- depth\n\n // Initialize parameter\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Tremolo` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (gain)\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'wave':\n if (value === undefined) {\n return this.lfo.type;\n }\n\n v = String(value).toLowerCase();\n\n if (v in Tremolo.WAVE_TYPES) {\n this.lfo.type = (typeof this.lfo.type === 'string') ? v : Tremolo.WAVE_TYPES[v];\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitude.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode -> GainNode (Output)\n this.input.connect(this.amplitude);\n this.amplitude.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value,\n 'wave' : this.lfo.type\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Tremolo]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Wah extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.autoWah = false;\n\n this.lowpass = context.createBiquadFilter();\n this.envelopeFollower = context.createWaveShaper();\n this.sensitivity = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = (typeof this.lowpass.type === 'string') ? 'lowpass' : (this.lowpass.LOWPASS || 0);\n this.lowpass.frequency.value = this.autoWah ? 20 : 350;\n this.lowpass.Q.value = 1;\n this.lowpass.gain.value = 0; // Not used\n\n this.envelopeFollower.curve = new Float32Array([1, 0, 1]);\n\n this.sensitivity.type = (typeof this.lowpass.type === 'string') ? 'lowpass' : (this.lowpass.LOWPASS || 0);\n this.sensitivity.frequency.value = 350;\n this.sensitivity.Q.value = 1;\n this.sensitivity.gain.value = 0; // Not used\n\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.depthRate = 0;\n\n // `Wah` is not connected by default\n this.state(false);\n this.connect();\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'auto':\n if (value === undefined) {\n return this.autoWah;\n }\n\n this.autoWah = Boolean(value);\n this.connect();\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.autoWah ? this.sensitivity.frequency.value : this.lowpass.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n if (this.autoWah) {\n this.sensitivity.frequency.value = v;\n this.lowpass.frequency.value = 20;\n } else {\n this.lowpass.frequency.value = v;\n }\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.autoWah ? 10000 * v : this.lowpass.frequency.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'resonance':\n if (value === undefined) {\n return this.autoWah ? this.sensitivity.Q.value : this.lowpass.Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n if (this.autoWah) {\n this.sensitivity.Q.value = v;\n this.lowpass.Q.value = 1;\n } else {\n this.lowpass.Q.value = v;\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (!this.autoWah && this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.sensitivity.disconnect(0);\n this.envelopeFollower.disconnect(0);\n this.lowpass.disconnect(0);\n this.depth.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n if (this.autoWah) {\n // GainNode (Input) -> BiquadFilterNode (Sensitivity) -> GainNode (Output)\n this.input.connect(this.sensitivity);\n this.sensitivity.connect(this.output);\n\n // WaveShaperNode (Envelope Follower) -> BiquadFilterNode (Low-Pass Filter) -> GainNode (Depth) -> AudioParam (frequency)\n this.input.connect(this.envelopeFollower);\n this.envelopeFollower.connect(this.lowpass);\n this.lowpass.connect(this.depth);\n this.depth.connect(this.sensitivity.frequency);\n } else {\n // GainNode (Input) -> BiquadFilterNode (Low-Pass Filter) -> GainNode (Output)\n this.input.connect(this.lowpass);\n this.lowpass.connect(this.output);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'auto' : this.autoWah,\n 'cutoff' : this.autoWah ? this.sensitivity.frequency.value : this.lowpass.frequency.value,\n 'depth' : this.autoWah ? this.depth.gain.value : this.depthRate,\n 'rate' : this.rate.value,\n 'resonance' : this.autoWah ? this.sensitivity.Q.value : this.lowpass.Q.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Wah]';\n }\n}\n","'use strict';\n\nimport { Analyser } from './Analyser';\nimport { Recorder } from './Recorder';\nimport { Session } from './Session';\nimport { Effector } from './Effectors/Effector';\nimport { Autopanner } from './Effectors/Autopanner';\nimport { AutopannerFallback } from './Effectors/AutopannerFallback';\nimport { Chorus } from './Effectors/Chorus';\nimport { Compressor } from './Effectors/Compressor';\nimport { Delay } from './Effectors/Delay';\nimport { Distortion } from './Effectors/Distortion';\nimport { EnvelopeGenerator } from './Effectors/EnvelopeGenerator';\nimport { Equalizer } from './Effectors/Equalizer';\nimport { Filter } from './Effectors/Filter';\nimport { Flanger } from './Effectors/Flanger';\nimport { Listener } from './Effectors/Listener';\nimport { Panner } from './Effectors/Panner';\nimport { Phaser } from './Effectors/Phaser';\nimport { PitchShifter } from './Effectors/PitchShifter';\nimport { Reverb } from './Effectors/Reverb';\nimport { Ringmodulator } from './Effectors/Ringmodulator';\nimport { Stereo } from './Effectors/Stereo';\nimport { Tremolo } from './Effectors/Tremolo';\nimport { Wah } from './Effectors/Wah';\n\n/**\n * This class is superclass that is the top in this library.\n * This library's users do not create the instance of `SoundModule`.\n * This class is used for inherit in subclass (`OscillatorModule`, `OneshotModule`, `AudioModule`, `MediaModule`, `StreamModule`, `MixerModule`, `ProcessorModule`).\n * Therefore, this class defines the common properties for each sound sources.\n * @constructor\n */\nexport class SoundModule {\n static NUMBER_OF_INPUTS = 2;\n static NUMBER_OF_OUTPUTS = 2;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n this.init(context, bufferSize);\n }\n\n /**\n * This method initials modules.\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * However, the opportunity for designating buffer size is not so much.\n * The reason why is that the constructor of `SoundModule` selects buffer size automaticly.\n * This buffer size can be changed explicitly by calling `resize` method.\n */\n init(context, bufferSize) {\n if (Array.isArray(this.modules) && (this.modules.length > 0)) {\n this.mastervolume.disconnect(0);\n this.mastervolume = null;\n\n this.processor.disconnect(0);\n this.processor = null;\n\n this.analyser.INPUT.disconnect(0);\n this.analyser = null;\n\n this.recorder.INPUT.disconnect(0);\n this.recorder = null;\n\n this.session.INPUT.disconnect(0);\n this.session = null;\n\n this.modules.forEach(module => {\n module.INPUT.disconnect(0);\n module.OUTPUT.disconnect(0);\n module = null;\n });\n\n this.modules = [];\n }\n\n this.context = context;\n this.sampleRate = context.sampleRate;\n\n let size = parseInt(bufferSize, 10);\n\n switch (size) {\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n break;\n default:\n size = 0;\n break;\n }\n\n this.mastervolume = context.createGain();\n this.processor = context.createScriptProcessor(size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context, size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n this.session = new Session(context, size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS, this.analyser);\n this.stereo = new Stereo(context, size);\n this.compressor = new Compressor(context, size);\n this.distortion = new Distortion(context, size);\n this.wah = new Wah(context, size);\n this.pitchshifter = new PitchShifter(context, size);\n this.equalizer = new Equalizer(context, size);\n this.filter = new Filter(context, size);\n this.autopanner = context.createStereoPanner ? new Autopanner(context, size) : new AutopannerFallback(context, size);\n this.tremolo = new Tremolo(context, size);\n this.ringmodulator = new Ringmodulator(context, size);\n this.phaser = new Phaser(context, size);\n this.flanger = new Flanger(context, size);\n this.chorus = new Chorus(context, size);\n this.delay = new Delay(context, size);\n this.reverb = new Reverb(context, size);\n this.panner = new Panner(context, size);\n this.listener = new Listener(context, size);\n this.envelopegenerator = new EnvelopeGenerator(context);\n\n // The default order for connection\n this.modules = [\n this.stereo,\n this.compressor,\n this.distortion,\n this.wah,\n this.pitchshifter,\n this.equalizer,\n this.filter,\n this.autopanner,\n this.tremolo,\n this.ringmodulator,\n this.phaser,\n this.flanger,\n this.chorus,\n this.delay,\n this.reverb,\n this.panner\n ];\n }\n\n /** @abstract */\n setup() {\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string} key This argument is property name.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number} This is returned as the value of designated property in the case of getter.\n */\n param(key, value) {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'mastervolume':\n if (value === undefined) {\n return this.mastervolume.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.mastervolume.gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n /** @abstract */\n ready() {\n return this;\n }\n\n /** @abstract */\n start() {\n return this;\n }\n\n /** @abstract */\n stop() {\n return this;\n }\n\n /** @abstract */\n get() {\n return this;\n }\n\n /**\n * This method changes buffer size for `ScriptProcessorNode`.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * This value is one of 0, 256, 512, 1024, 2048, 4096, 8192, 16384.\n * @return {SoundModule} This is returned for method chain.\n */\n resize(bufferSize) {\n this.init(this.context, bufferSize);\n return this;\n }\n\n /**\n * This method gets buffer size for `ScriptProcessorNode`.\n * @return {number} This is returned as buffer size for `ScriptProcessorNode`.\n */\n getBufferSize() {\n return this.processor.bufferSize;\n }\n\n /**\n * This method installs customized effector.\n * @param {string} name This argument is in order to select effector.\n * @param {Effector} effector This argument is the subclass that extends `Effector` class.\n * @return {SoundModule} This is returned for method chain.\n */\n install(name, effector) {\n if (!(effector instanceof Effector)) {\n return this;\n }\n\n if (String(name) in this) {\n return this;\n }\n\n this[name] = effector;\n\n if (this.modules.every(module => module !== effector)) {\n this.modules.push(effector);\n }\n\n return this;\n }\n\n /**\n * This method connects nodes that are defined by this library and Web Audio API.\n * @param {AudioNode} source This argument is `AudioNode` for input of sound.\n * @param {Array.<Effector>} connects This argument is array for changing the default connection.\n * @return {SoundModule} This is returned for method chain.\n */\n connect(source, connects) {\n // Customize connection ?\n if (Array.isArray(connects)) {\n this.modules = connects;\n }\n\n // Start connection\n // AudioSourceNode (Input)-> node -> ... -> node -> GainNode (Master Volume) -> AnalyserNode -> AudioDestinationNode (Output)\n source.disconnect(0); // Clear connection\n\n if (this.modules.length > 0) {\n source.connect(this.modules[0].INPUT);\n } else {\n source.connect(this.mastervolume);\n }\n\n for (let i = 0, len = this.modules.length; i < len; i++) {\n // Clear connection\n this.modules[i].OUTPUT.disconnect(0);\n\n if (i < (this.modules.length - 1)) {\n // Connect to next node\n this.modules[i].OUTPUT.connect(this.modules[i + 1].INPUT);\n } else {\n this.modules[i].OUTPUT.connect(this.mastervolume);\n }\n }\n\n this.mastervolume.connect(this.context.destination);\n\n // for analyser\n this.mastervolume.connect(this.analyser.INPUT);\n\n // for recording\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.INPUT.connect(this.context.destination);\n\n // for session\n this.mastervolume.connect(this.session.INPUT);\n this.session.INPUT.connect(this.context.destination);\n\n return this;\n }\n\n /**\n * This method gets the instance of module that is defined by this library. This method enables to access the instance of module by unified call.\n * @param {string} module This argument is module's name.\n * @return {Analyser|Recorder|Session|Effector|Listener|EnvelopeGenerator|Glide|VocalCanceler|NoiseGate|NoiseSuppressor} This value is the instance of module.\n */\n module(module) {\n const m = String(module).replace(/-/g, '').toLowerCase();\n\n switch (m) {\n case 'analyser' :\n case 'recorder' :\n case 'session' :\n case 'stereo' :\n case 'compressor' :\n case 'distortion' :\n case 'wah' :\n case 'pitchshifter' :\n case 'equalizer' :\n case 'filter' :\n case 'autopanner' :\n case 'tremolo' :\n case 'ringmodulator':\n case 'phaser' :\n case 'flanger' :\n case 'chorus' :\n case 'delay' :\n case 'reverb' :\n case 'panner' :\n case 'listener' :\n return this[m];\n case 'envelopegenerator':\n case 'eg' :\n return this.envelopegenerator;\n case 'glide':\n if (m in this) {\n return this[m]; // OscillatorModule\n }\n\n // fall through\n case 'vocalcanceler':\n if (m in this) {\n return this[m]; // AudioModule, MediaModule\n }\n\n // fall through\n case 'noisegate' :\n case 'noisesuppressor':\n if (m in this) {\n return this[m]; // StreamModule\n }\n\n // fall through\n default:\n return this[m]; // Installed effector\n }\n }\n\n /**\n * This method starts effectors.\n * @param {number} startTime This argument is used for scheduling parameter.\n * @return {SoundModule} This is returned for method chain.\n */\n on(startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.stereo.start(s);\n this.chorus.start(s);\n this.flanger.start(s);\n this.phaser.start(s);\n this.autopanner.start(s);\n this.tremolo.start(s);\n this.ringmodulator.start(s);\n this.wah.start(s);\n this.filter.start(s);\n\n return this;\n }\n\n /**\n * This method stops effectors.\n * @param {number} stopTime This argument is used for scheduling parameter.\n * @return {SoundModule} This is returned for method chain.\n */\n off(stopTime) {\n let s = parseFloat(stopTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.stereo.stop(s);\n this.chorus.stop(s);\n this.flanger.stop(s);\n this.phaser.stop(s);\n this.autopanner.stop(s);\n this.tremolo.stop(s);\n this.ringmodulator.stop(s);\n this.wah.stop(s);\n // this.filter.stop(s);\n\n return this;\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {};\n\n for (const module in this) {\n if (Object.prototype.toString.call(this[module]) === '[object Function]') {\n continue;\n }\n\n const m = module.toLowerCase();\n\n if (m === 'mastervolume') {\n params[m] = this[module].gain.value; // AudioParam\n } else if ((Object.prototype.toString.call(this[module]) === '[object Object]') && ('params' in this[module])) {\n params[m] = this[module].params();\n }\n }\n\n return params;\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for the instance of `OscillatorNode`.\n * @constructor\n */\nexport class Oscillator {\n // 1 Octave = 1200 cent\n static OCTAVE = 1200;\n\n // for legacy browsers\n static WAVE_TYPES = {\n 'sine' : 0,\n 'square' : 1,\n 'sawtooth' : 2,\n 'triangle' : 3\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {boolean} state This argument is initial state.\n */\n constructor(context, state) {\n this.isActive = state;\n\n this.context = context;\n\n this.source = context.createOscillator();\n\n // for legacy browsers\n this.source.setPeriodicWave = this.source.setPeriodicWave || this.source.setWaveTable;\n this.source.start = this.source.start || this.source.noteOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n this.volume = context.createGain();\n\n // in order to not call in duplicate `start` or `stop` method in the instance of `OscillatorNode`\n this.isStop = true;\n\n this.octave = 0;\n this.fine = 0;\n this.customs = {\n 'real' : new Float32Array([0, 1]),\n 'imag' : new Float32Array([0, 1])\n };\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|string|Oscillator} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.source.type;\n }\n\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n v = String(value).toLowerCase();\n\n if (v in Oscillator.WAVE_TYPES) {\n this.source.type = (typeof this.source.type === 'string') ? v : Oscillator.WAVE_TYPES[v];\n }\n } else {\n // Custom wave\n if (('real' in value) && ('imag' in value)) {\n let reals = null;\n let imags = null;\n\n if (value.real instanceof Float32Array) {\n reals = value.real;\n } else if (Array.isArray(value.real)) {\n reals = new Float32Array(value.real);\n }\n\n if (value.imag instanceof Float32Array) {\n imags = value.imag;\n } else if (Array.isArray(value.imag)) {\n imags = new Float32Array(value.imag);\n }\n\n if ((reals instanceof Float32Array) && (imags instanceof Float32Array)) {\n const MAX_SIZE = 4096; // This size is defined by specification\n\n if (reals.length > MAX_SIZE) { reals = reals.subarray(0, MAX_SIZE); }\n if (imags.length > MAX_SIZE) { imags = imags.subarray(0, MAX_SIZE); }\n\n // The 1st value is fixed by 0 (This is is defined by specification)\n if (reals[0] !== 0) { reals[0] = 0; }\n if (imags[0] !== 0) { imags[0] = 0; }\n\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n this.customs.real = reals;\n this.customs.imag = imags;\n }\n }\n }\n\n break;\n case 'octave':\n if (value === undefined) {\n return this.octave;\n }\n\n v = parseFloat(value);\n min = -4800 / Oscillator.OCTAVE;\n max = 4800 / Oscillator.OCTAVE;\n\n if ((v >= min) && (v <= max)) {\n this.octave = v;\n this.source.detune.value = this.fine + (v * Oscillator.OCTAVE);\n }\n\n break;\n case 'fine':\n if (value === undefined) {\n return this.fine;\n }\n\n v = parseFloat(value);\n min = -Oscillator.OCTAVE;\n max = Oscillator.OCTAVE;\n\n if ((v >= min) && (v <= max)) {\n this.fine = v;\n this.source.detune.value = v + (this.octave * Oscillator.OCTAVE);\n }\n\n break;\n case 'volume':\n case 'gain' :\n if (value === undefined) {\n return this.volume.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.volume.gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method connects nodes.\n * @param {AudioNode} output This argument is the instance of `AudioNode` as output.\n * @return {Oscillator} This is returned for method chain.\n */\n ready(output) {\n if (this.isActive) {\n // for saving value\n const params = {\n 'type' : this.source.type,\n 'frequency' : this.source.frequency.value,\n 'detune' : this.source.detune.value\n };\n\n if (!this.isStop) {\n this.source.stop(this.context.currentTime);\n this.source.disconnect(0);\n }\n\n this.source = this.context.createOscillator();\n\n // for legacy browsers\n this.source.setPeriodicWave = this.source.setPeriodicWave || this.source.setWaveTable;\n this.source.start = this.source.start || this.source.noteOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n if (params.type === 'custom') {\n // Custom wave\n const reals = this.customs.real;\n const imags = this.customs.imag;\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n } else {\n this.source.type = params.type;\n }\n\n this.source.frequency.value = params.frequency;\n this.source.detune.value = params.detune;\n\n this.volume.connect(output);\n }\n\n return this;\n }\n\n /**\n * This method starts sound.\n * @param {number} startTime This argument is the start time.\n * @return {Oscillator} This is returned for method chain.\n */\n start(startTime) {\n if (this.isActive) {\n this.source.start(startTime);\n this.isStop = false;\n } else {\n if (!this.isStop) {\n this.source.stop(this.context.currentTime);\n this.isStop = true;\n }\n\n this.source.disconnect(0);\n }\n\n return this;\n }\n\n /**\n * This method stops sound.\n * @param {number} stopTime This argument is the stop time.\n * @return {Oscillator} This is returned for method chain.\n */\n stop(stopTime) {\n if (!this.isStop) {\n this.source.stop(stopTime);\n this.source.disconnect(0);\n\n this.isStop = true;\n }\n\n return this;\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Oscillator} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `OscillatorNode`.\n * @return {OscillatorNode}\n */\n get() {\n return this.source;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule Oscillator]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Glide.\n * @constructor\n */\nexport class Glide {\n static LINEAR = 'linear';\n static EXPONENTIAL = 'exponential';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.frequencies = {\n 'start' : -1, // Abnormal value for the 1st sound\n 'end' : 0\n };\n\n this.time = 0; // Glide time\n this.type = Glide.LINEAR; // either 'linear' or 'exponential'\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Glide} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'time':\n if (value === undefined) {\n return this.time;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.time = v;\n }\n\n break;\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === Glide.LINEAR) || (v === Glide.EXPONENTIAL)) {\n this.type = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method sets frequencies for Glide.\n * @param {number} frequency This argument is the frequency at which glide ends.\n * @return {Glide} This is returned for method chain.\n */\n ready(frequency) {\n this.frequencies.end = frequency;\n\n const diff = (this.frequencies.start === -1) ? 0 : (this.frequencies.end - this.frequencies.start);\n\n if ((this.frequencies.start === -1) || (this.time === 0) || (diff === 0)) {\n // The 1st sound or Glide OFF or The same sound\n this.frequencies.start = this.frequencies.end;\n }\n\n return this;\n }\n\n /**\n * This method starts Glide.\n * @param {OscillatorNode} oscillator This argument is the instance of `OscillatorNode`.\n * @param {number} startTime This argument is the start time of Glide.\n * @return {Glide} This is returned for method chain.\n */\n start(oscillator, startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t0 = s;\n const t1 = t0 + this.time;\n\n // Start Glide\n oscillator.frequency.cancelScheduledValues(t0);\n oscillator.frequency.setValueAtTime(this.frequencies.start, t0);\n oscillator.frequency[`${this.type}RampToValueAtTime`](this.frequencies.end, t1);\n\n return this;\n }\n\n /**\n * This method stops Glide. Moreover, This method prepares for next Glide.\n * @return {Glide} This is returned for method chain.\n */\n stop() {\n // Stop Glide or on the way of Glide\n this.frequencies.start = this.frequencies.end;\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule Glide]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { Oscillator } from './Oscillator';\nimport { Glide } from './Glide';\n\n/**\n * This subclass defines properties for creating sound.\n * Actually, properties for creating sound is defined in private class (`Oscillator`).\n * Therefore, this class manages these private classes for creating sound.\n * @constructor\n * @extends {SoundModule}\n */\nexport class OscillatorModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n /** @type {Array.<Oscillator>} */\n this.sources = [];\n\n // for scheduling\n this.times = {\n 'start' : 0,\n 'duration' : 0\n };\n\n // This flag determines whether sound wave is drawn\n this.isAnalyser = false;\n\n this.glide = new Glide(context);\n }\n\n /**\n * This method creates the instances of `Oscillator`.\n * @param {Array.<boolean>|boolean} states This argument is initial state in the instance of `Oscillator`.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n setup(states) {\n // Clear\n this.sources.length = 0;\n\n if (!Array.isArray(states)) {\n states = [states];\n }\n\n for (let i = 0, len = states.length; i < len; i++) {\n this.sources[i] = new Oscillator(this.context, Boolean(states[i]));\n this.envelopegenerator.setGenerator(i);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|OscillatorModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n return (r === undefined) ? this : r;\n }\n }\n\n /**\n * This method schedules the time of start and stop.\n * @param {number} startTime This argument is the start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n ready(startTime, duration) {\n const s = parseFloat(startTime);\n const d = parseFloat(duration);\n\n this.times.start = (s >= 0) ? s : 0;\n this.times.duration = (d >= 0) ? d : 0;\n\n this.envelopegenerator.clear(true);\n\n return this;\n }\n\n /**\n * This method starts some sounds that are active at the same time.\n * @param {Array.<number>}|number} frequencies This argument each oscillator frequency. The default value is 0 Hz.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n start(frequencies, connects, processCallback) {\n const startTime = this.context.currentTime + this.times.start;\n\n // Validate the 1st argument\n if (!Array.isArray(frequencies)) {\n frequencies = [frequencies];\n }\n\n for (let i = 0, len = frequencies.length; i < len; i++) {\n const f = parseFloat(frequencies[i]);\n frequencies[i] = (f >= 0) ? f : 0;\n }\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // ScriptProcessorNode (Mix oscillators) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor, connects);\n\n for (let i = 0, len = frequencies.length; i < len; i++) {\n if (i >= this.sources.length) {\n break;\n }\n\n const oscillator = this.sources[i];\n const frequency = frequencies[i];\n\n // GainNode (Volume) -> ScriptProcessorNode (Mix oscillators)\n oscillator.ready(this.processor);\n\n // OscillatorNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume)\n this.envelopegenerator.ready(i, oscillator.source, oscillator.volume);\n\n this.glide.ready(frequency).start(oscillator.source, startTime);\n\n oscillator.start(startTime);\n }\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n // Stop ?\n if (this.envelopegenerator.isStop()) {\n // Stop\n const stopTime = this.context.currentTime;\n\n for (const source of this.sources) {\n source.stop(stopTime);\n }\n\n this.off(stopTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method stops active sounds.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n stop() {\n const stopTime = this.context.currentTime + this.times.start + this.times.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.glide.stop();\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets the instance of `Oscillator` that is used in `OscillatorModule`.\n * @param {number} index This argument is required in the case of designating `Oscillator`.\n * @return {Array.<Oscillator>|Oscillator}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /**\n * This method returns the number of oscillators.\n * @return {number} This is returned as the number of oscillators.\n */\n length() {\n return this.sources.length;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.oscillator = {\n 'glide' : {\n 'type' : this.glide.param('type'),\n 'time' : this.glide.param('time')\n }\n };\n\n for (let i = 0, len = this.sources.length; i < len; i++) {\n const source = this.sources[i];\n\n params.oscillator[`oscillator${i}`] = {\n 'state' : source.state(),\n 'gain' : source.param('gain'),\n 'type' : source.param('type'),\n 'octave' : source.param('octave'),\n 'fine' : source.param('fine')\n };\n }\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\n/**\n * This subclass defines properties for playing the one-shot audio.\n * @constructor\n * @extends {SoundModule}\n */\nexport class OneshotModule extends SoundModule {\n static ERROR_AJAX = 'error';\n static ERROR_AJAX_TIMEOUT = 'timeout';\n static ERROR_DECODE = 'decode';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.sources = []; /** @type {Array.<AudioBufferSourceNode>} */\n this.resources = []; /** @type {Array.<string>} */\n this.buffers = []; /** @type {Array.<AudioBuffer>} */\n this.volumes = []; /** @type {Array.<GainNode>} */\n this.isStops = []; /** @type {Array.<boolean>} in order to not call in duplicate `start` or `stop` method in the instance of `AudioBufferSourceNode` */\n\n // for audio sources\n this.settings = []; /** @type {Array.<object>} */\n\n // for scheduling\n this.times = {\n 'start' : 0,\n 'duration' : 0\n };\n\n this.transpose = 1.0;\n\n this.isStop = true;\n\n // If the error is at least 1, this method aborts the all of connections.\n // Therefore, this flag are shared with the all instances of `XMLHttpRequest`.\n this.isLoadError = false;\n\n // This flag determines whether sound wave is drawn\n this.isAnalyser = false;\n }\n\n /**\n * This method creates the instances of `AudioBuffer` by Ajax.\n * @param {Array.<string>|Array.<AudioBuffer>} resources This argument is either URLs or the instances of `AudioBuffer` for audio resources.\n * @param {Array.<object>} settings This argument is the properties of each audio sources.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n setup(resources, settings, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('resources' in properties) {\n resources = properties.resources;\n }\n\n if ('settings' in properties) {\n settings = properties.settings;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!Array.isArray(resources)) {\n resources = [resources];\n }\n\n this.resources = resources;\n\n if (!Array.isArray(settings)) {\n settings = [settings];\n }\n\n this.buffers.length = resources.length;\n\n for (let i = 0, len = settings.length; i < len; i++) {\n if ('buffer' in settings[i]) {\n const buffer = parseInt(settings[i].buffer, 10);\n\n if ((buffer >= 0) && (buffer < this.buffers.length)) {\n settings[i].buffer = buffer;\n } else {\n return this;\n }\n } else {\n return this;\n }\n\n settings[i].rate = (('rate' in settings[i]) && (settings[i].rate >= 0)) ? parseFloat(settings[i].rate) : 1;\n settings[i].loop = ('loop' in settings[i]) ? Boolean(settings[i].loop) : false;\n settings[i].start = (('start' in settings[i]) && (settings[i].start >= 0)) ? parseFloat(settings[i].start) : 0;\n settings[i].end = (('end' in settings[i]) && (settings[i].end >= 0)) ? parseFloat(settings[i].end) : 0;\n settings[i].volume = (('volume' in settings[i]) && (settings[i].volume >= 0) && (settings[i].volume <= 1)) ? parseFloat(settings[i].volume) : 1;\n\n this.isStops[i] = true;\n this.volumes[i] = this.context.createGain();\n this.envelopegenerator.setGenerator(i);\n }\n\n this.settings = settings;\n\n const t = parseInt(timeout, 10);\n\n for (let i = 0, len = this.resources.length; i < len; i++) {\n if (typeof this.resources[i] === 'string') {\n // Get the instances of `AudioBuffer` from the designated URLs.\n this.load(this.resources[i], i, t, successCallback, errorCallback, progressCallback);\n } else if (this.resources[i] instanceof AudioBuffer) {\n // Get the instances of `AudioBuffer` directly\n this.buffers[i] = this.resources[i];\n }\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|OneshotModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'transpose':\n if (value === undefined) {\n return this.transpose;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.transpose = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method schedules the time of start and stop.\n * @param {number} startTime This argument is the start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n ready(startTime, duration) {\n const s = parseFloat(startTime);\n const d = parseFloat(duration);\n\n this.times.start = (s >= 0) ? s : 0;\n this.times.duration = (d >= 0) ? d : 0;\n\n this.envelopegenerator.clear(false);\n\n return this;\n }\n\n /**\n * This method starts one-shot audio with the designated playback rate and volume.\n * @param {number} index This argument is in order to select the instance of `AudioBufferSourceNode`.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n start(index, connects, processCallback) {\n const selectedIndex = parseInt(index, 10);\n\n if (isNaN(selectedIndex) || (selectedIndex < 0) || (selectedIndex >= this.settings.length)) {\n return this;\n }\n\n const bufferIndex = this.settings[selectedIndex].buffer;\n const playbackRate = this.settings[selectedIndex].rate;\n const loop = this.settings[selectedIndex].loop;\n const loopStart = this.settings[selectedIndex].start;\n const loopEnd = this.settings[selectedIndex].end;\n const volume = this.settings[selectedIndex].volume;\n\n if (!(this.buffers[bufferIndex] instanceof AudioBuffer)) {\n // `setup` method has not been invoked\n return this;\n }\n\n // The following code is unnecessary, because `AudioBufferSourceNode` is the target of garbage collection in the case of no references and no sound\n // (If there is this code, application cannot repeat hits).\n\n // if (this.sources[selectedIndex] instanceof AudioBufferSourceNode) {\n // this.sources[selectedIndex].stop(this.context.currentTime);\n // this.sources[selectedIndex].disconnect(0);\n // this.sources[selectedIndex] = null;\n // }\n\n const source = this.context.createBufferSource();\n\n // for legacy browsers\n source.start = source.start || source.noteGrainOn;\n source.stop = source.stop || source.noteOff;\n\n source.buffer = this.buffers[bufferIndex];\n\n // Set properties\n source.playbackRate.value = playbackRate * this.transpose;\n source.loop = loop;\n source.loopStart = loopStart;\n source.loopEnd = loopEnd;\n\n this.volumes[selectedIndex].gain.value = volume;\n\n this.envelopegenerator.clear(false);\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(selectedIndex, source, this.volumes[selectedIndex]);\n this.volumes[selectedIndex].connect(this.processor);\n this.connect(this.processor, connects);\n\n const startTime = this.context.currentTime + this.times.start;\n\n if (source.loop) {\n source.start(startTime, (startTime + source.loopStart), (source.loopEnd - startTime));\n } else {\n source.start(startTime);\n }\n\n this.sources[selectedIndex] = source;\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.isStops[selectedIndex] = false;\n\n // in the case of scheduling stop time\n if (this.times.stop > 0) {\n window.setTimeout(() => {\n this.stop(selectedIndex);\n }, (this.times.stop * 1000));\n }\n\n // Call on stopping audio\n source.onended = () => {\n this.isStops[selectedIndex] = true;\n };\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n this.isStop = this.isStops.every(element => element);\n\n if (this.isStop) {\n // Stop\n\n this.off(this.context.currentTime);\n\n this.envelopegenerator.clear(false);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method stops the designated one-shot audio.\n * @param {number} index This argument is in order to select the instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n stop(index) {\n const selectedIndex = parseInt(index, 10);\n\n if (isNaN(selectedIndex) || (selectedIndex < 0) || (selectedIndex >= this.settings.length)) {\n return this;\n }\n\n const bufferIndex = this.settings[selectedIndex].buffer;\n\n if (!((this.buffers[bufferIndex] instanceof AudioBuffer) && (this.sources[selectedIndex] instanceof AudioBufferSourceNode))) {\n return this;\n }\n\n const stopTime = this.context.currentTime + this.times.start + this.times.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets the instance of `AudioBuffer` that is used in `OneshotModule`.\n * @param {number} index This argument is required in the case of designating `AudioBuffer`.\n * @return {Array.<AudioBuffer>|AudioBuffer}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.buffers.length)) ? this.buffers[i] : this.buffers;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.oneshot = {\n 'transpose' : this.transpose\n };\n\n return params;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates the instances of `AudioBuffer`.\n * @param {string} url This argument is resource URL for one-shot audio.\n * @param {number} index This argument is in order to assign the instance of `AudioBuffer`.\n * @param {number} timeout This argument is Ajax timeout.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {OneshotModule} This is returned for method chain.\n */\n load(url, index, timeout, successCallback, errorCallback, progressCallback) {\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = (timeout > 0) ? timeout : 60000;\n\n xhr.ontimeout = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, OneshotModule.ERROR_AJAX_TIMEOUT);\n }\n\n this.isLoadError = true;\n };\n\n xhr.onprogress = event => {\n if (this.isLoadError) {\n xhr.abort();\n } else if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, OneshotModule.ERROR_AJAX);\n }\n\n this.isLoadError = true;\n };\n\n // Success\n xhr.onload = event => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = audioBuffer => {\n this.buffers[index] = audioBuffer;\n\n // The creating the instances of `AudioBuffer` has completed ?\n for (const buffer of this.buffers) {\n if (buffer === undefined) {\n return;\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(event, this.buffers);\n }\n };\n\n const decodeErrorCallback = error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error, OneshotModule.ERROR_DECODE);\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n\n return this;\n }\n\n /**\n * This method resets settings.\n * @param {number} index This argument is in order to select target setting.\n * @param {string} key This argument is in order to select parameter.\n * @param {number|boolean} value This argument is new value.\n * @return {OneshotModule} This is returned for method chain.\n */\n reset(index, key, value) {\n const selectedIndex = parseInt(index, 10);\n\n if (String(key).toLowerCase() in this.settings[selectedIndex]) {\n this.settings[selectedIndex][key.toLowerCase()] = value;\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[OneshotModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\nexport class NoiseModule extends SoundModule {\n static WHITE_NOISE = 'whitenoise';\n static PINK_NOISE = 'pinknoise';\n static BROWNIAN_NOISE = 'browniannoise';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.type = NoiseModule.WHITE_NOISE;\n\n this.envelopegenerator.setGenerator(0);\n\n this.isAnalyser = false;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|string|NoiseModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = '';\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === NoiseModule.WHITE_NOISE) || (v === NoiseModule.PINK_NOISE) || (v === NoiseModule.BROWNIAN_NOISE)) {\n this.type = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n start(connects) {\n const startTime = this.context.currentTime;\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(this.envelopegenerator.getGenerator(0), connects);\n\n // ScriptProcessorNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.on(startTime);\n\n const bufferSize = this.processor.bufferSize;\n\n let lastOut = 0;\n\n this.processor.onaudioprocess = event => {\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.envelopegenerator.isStop()) {\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n } else {\n switch (this.type) {\n case NoiseModule.WHITE_NOISE:\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = 2 * (Math.random() - 0.5);\n outputRs[i] = 2 * (Math.random() - 0.5);\n }\n\n break;\n case NoiseModule.PINK_NOISE:\n // ref: https://noisehack.com/generate-noise-web-audio-api/\n let b0 = 0;\n let b1 = 0;\n let b2 = 0;\n let b3 = 0;\n let b4 = 0;\n let b5 = 0;\n let b6 = 0;\n\n for (let i = 0; i < bufferSize; i++) {\n const white = (Math.random() * 2) - 1;\n\n b0 = (0.99886 * b0) + (white * 0.0555179);\n b1 = (0.99332 * b1) + (white * 0.0750759);\n b2 = (0.96900 * b2) + (white * 0.1538520);\n b3 = (0.86650 * b3) + (white * 0.3104856);\n b4 = (0.55000 * b4) + (white * 0.5329522);\n b5 = (-0.7616 * b5) - (white * 0.0168980);\n\n outputLs[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + (white * 0.5362);\n outputRs[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + (white * 0.5362);\n\n outputLs[i] *= 0.11;\n outputRs[i] *= 0.11;\n\n b6 = white * 0.115926;\n }\n\n break;\n case NoiseModule.BROWNIAN_NOISE:\n // ref: https://noisehack.com/generate-noise-web-audio-api/\n for (let i = 0; i < bufferSize; i++) {\n const white = (Math.random() * 2) - 1;\n\n outputLs[i] = (lastOut + (0.02 * white)) / 1.02;\n outputRs[i] = (lastOut + (0.02 * white)) / 1.02;\n\n lastOut = (lastOut + (0.02 * white)) / 1.02;\n\n outputLs[i] *= 3.5;\n outputRs[i] *= 3.5;\n }\n\n break;\n default:\n break;\n }\n }\n };\n\n return this;\n }\n\n /** @override */\n stop() {\n const stopTime = this.context.currentTime;\n\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[NoiseModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Vocal Canceler.\n * @constructor\n */\nexport class VocalCanceler {\n constructor() {\n this.depth = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|VocalCanceler} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method removes vocal part in the played audio.\n * @param {number} dataL This argument is gain level for Left channel.\n * @param {number} dataR This argument is gain level for Right channel.\n * @return {number} This is returned as audio data except vocal part.\n */\n start(dataL, dataR) {\n return dataL - (this.depth * dataR);\n }\n\n /** @override */\n toString() {\n return '[AudioModule VocalCanceler]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { VocalCanceler } from './VocalCanceler';\n\n/**\n * This subclass defines properties for playing the single audio.\n * This class creates audio player that has higher features than `HTMLAudioElment`.\n * But, this class is disadvantage to play the many one shot audios.\n * In the case of that, developer should use `OneshotModule`.\n * @constructor\n * @extends {SoundModule}\n */\nexport class AudioModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.source = context.createBufferSource(); // for the instance of `AudioBufferSourceNode`\n this.buffer = null; // for the instance of `AudioBuffer`\n\n this.currentTime = 0;\n\n this.paused = true;\n\n this.callbacks = {\n 'decode' : () => {},\n 'ready' : () => {},\n 'start' : () => {},\n 'stop' : () => {},\n 'update' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n\n this.vocalcanceler = new VocalCanceler();\n }\n\n /**\n * This method sets callback functions.\n * @param {string|object} key This argument is property name.\n * This argument is pair of property and value in the case of associative array.\n * @param {function} value This argument is callback function.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n setup(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.setup(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(value) === '[object Function]') {\n this.callbacks[k] = value;\n }\n }\n }\n\n this.envelopegenerator.setGenerator(0);\n this.envelopegenerator.param({\n 'attack' : 0,\n 'decay' : 0.01,\n 'sustain' : 1,\n 'release' : 0.01\n });\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = 0;\n let min = 0;\n let max = 0;\n\n switch (k) {\n case 'playbackrate':\n if (value === undefined) {\n return this.source.playbackRate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1024;\n\n if ((v >= min) && (v <= max)) {\n this.source.playbackRate.value = v;\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / v)), true);\n }\n\n break;\n case 'loop' :\n case 'looping':\n if (value === undefined) {\n return this.source.loop;\n }\n\n this.source.loop = Boolean(value);\n\n break;\n case 'currenttime':\n if (value === undefined) {\n return this.currentTime;\n }\n\n if (this.buffer instanceof AudioBuffer) {\n v = parseFloat(value);\n max = this.buffer.duration;\n min = 0;\n\n if ((v >= min) && (v <= max)) {\n if (this.paused) {\n this.currentTime = v;\n } else {\n this.stop();\n this.start(v);\n }\n }\n } else {\n this.currentTime = 0;\n }\n\n break;\n case 'duration':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.duration : 0; // Getter only\n case 'samplerate':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.sampleRate : this.sampleRate; // Getter only\n case 'channels':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.numberOfChannels : 0; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method creates the instance of `AudioBuffer` from `ArrayBuffer` or sets the instanceof `AudioBuffer`.\n * @param {ArrayBuffer|AudioBuffer} buffer This argument is the instance of `ArrayBuffer` or `AudioBuffer`.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n ready(buffer) {\n if (buffer instanceof ArrayBuffer) {\n this.buffer = null;\n\n const successCallback = b => {\n this.buffer = b;\n\n this.analyser.start('timeoverview', 0, this.buffer);\n this.analyser.start('timeoverview', 1, this.buffer);\n\n this.callbacks.ready(this.buffer);\n };\n\n this.context.decodeAudioData(buffer, successCallback, this.callbacks.error);\n\n this.callbacks.decode(buffer);\n } else if (buffer instanceof AudioBuffer) {\n this.buffer = buffer;\n }\n\n return this;\n }\n\n /**\n * This method starts audio from the designated time.\n * @param {number} startTime This argument is the time that audio is started at. The default value is 0.\n * @param {number} endTime This argument is the time that audio is ended at. The default value is audio duration.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n start(startTime, endTime, connects, processCallback) {\n if ((this.buffer instanceof AudioBuffer) && this.paused) {\n // This value is `AudioContext#currentTime`\n const currentTime = this.context.currentTime;\n\n const start = parseFloat(startTime);\n const end = parseFloat(endTime);\n\n if (end >= 0) {\n this.currentTime = ((start >= 0) && (start <= end)) ? start : 0;\n } else {\n this.currentTime = ((start >= 0) && (start <= this.buffer.duration)) ? start : 0;\n }\n\n const playbackRate = this.source.playbackRate.value;\n const loop = this.source.loop;\n\n this.source = this.context.createBufferSource();\n\n // for legacy browsers\n this.source.start = this.source.start || this.source.noteGrainOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n this.source.buffer = this.buffer;\n this.source.playbackRate.value = playbackRate;\n this.source.loop = loop;\n this.source.loopStart = this.currentTime;\n this.source.loopEnd = (end >= 0) ? end : this.buffer.duration;\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor, connects);\n\n if (isNaN(start)) {\n this.source.start(currentTime);\n } else if (end >= 0) {\n this.source.start(currentTime, this.currentTime, (end - start));\n } else {\n this.source.start(currentTime, this.currentTime, (this.buffer.duration - this.currentTime));\n }\n\n this.analyser.start('time');\n this.analyser.start('fft');\n\n this.paused = false;\n\n this.envelopegenerator.start(currentTime);\n\n if (end >= 0) {\n this.envelopegenerator.stop((currentTime + ((end - start) / this.source.playbackRate.value)), true);\n } else {\n this.envelopegenerator.stop((currentTime + ((this.buffer.duration - start) / this.source.playbackRate.value)), true);\n }\n\n this.on(currentTime);\n\n this.callbacks.start(this.source, this.currentTime);\n\n const bufferSize = this.processor.bufferSize;\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.currentTime < Math.floor(this.source.loopEnd)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.vocalcanceler.start(inputLs[i], inputRs[i]);\n outputRs[i] = this.vocalcanceler.start(inputRs[i], inputLs[i]);\n\n this.currentTime += ((1 * this.source.playbackRate.value) / this.source.buffer.sampleRate);\n\n this.callbacks.update(this.source, this.currentTime);\n }\n\n this.analyser.domain('timeoverview', 0).update(this.currentTime);\n this.analyser.domain('timeoverview', 1).update(this.currentTime);\n } else {\n if (this.source.loop) {\n this.stop();\n\n if ((this.analyser.domain('timeoverview', 0).param('mode') === 'sprite') || (this.analyser.domain('timeoverview', 1).param('mode') === 'sprite')) {\n this.start(this.source.loopStart, this.source.loopEnd, connects, processCallback);\n } else {\n this.start(0, this.buffer.duration, connects, processCallback);\n }\n } else {\n this.end();\n }\n }\n };\n }\n }\n\n return this;\n }\n\n /**\n * This method stops audio.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n stop() {\n if ((this.buffer instanceof AudioBuffer) && !this.paused) {\n const stopTime = this.context.currentTime;\n\n this.source.stop(stopTime);\n\n this.off(stopTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Clear\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.paused = true;\n this.callbacks.stop(this.source, this.currentTime);\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `AudioBufferSourceNode`.\n * @return {AudioBufferSourceNode}\n * @override\n */\n get() {\n return this.source;\n }\n\n /**\n * This method starts or stops audio according to audio state.\n * @param {number} startTime This argument is the time that audio is started at. The default value is 0.\n * @param {number} endTime This argument is the time that audio is ended at. The default value is audio duration.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {AudioModule} This is returned for method chain.\n */\n toggle(startTime, endTime, connects, processCallback) {\n if (this.paused) {\n this.start(startTime, endTime, connects, processCallback);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method rewinds audio.\n * @return {AudioModule} This is returned for method chain.\n */\n end() {\n this.stop();\n this.currentTime = 0;\n this.callbacks.ended(this.source, this.currentTime);\n\n return this;\n }\n\n /**\n * This method determines whether the instance of `AudioBuffer` exists.\n * @return {boolean} If the instance of `AudioBuffer` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isBuffer() {\n return this.buffer instanceof AudioBuffer;\n }\n\n /**\n * This method determines whether the instance of `AudioBufferSourceNode` exists.\n * @return {boolean} If the instance of `AudioBufferSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isSource() {\n return (this.source instanceof AudioBufferSourceNode) && (this.source.buffer instanceof AudioBuffer);\n }\n\n /**\n * This method determines whether the audio is paused.\n * @return {boolean} If the audio is paused, this value is `true`. Otherwise, this value is `false`.\n */\n isPaused() {\n return this.paused;\n }\n\n /**\n * This method is getter or setter for fade-in time.\n * @param {number} time This argument is fade-in time. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as fade-in time. Otherwise, this is returned for method chain.\n */\n fadeIn(time) {\n if (time === undefined) {\n return this.envelopegenerator.param('attack');\n }\n\n this.envelopegenerator.param('attack', time);\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n\n return this;\n }\n\n /**\n * This method is getter or setter for fade-out time.\n * @param {number} time This argument is fade-out time. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as fade-out time. Otherwise, this is returned for method chain.\n */\n fadeOut(time) {\n if (time === undefined) {\n return this.envelopegenerator.param('release');\n }\n\n this.envelopegenerator.param('release', time);\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n\n return this;\n }\n\n /**\n * This method slices the instance of `AudioBuffer`.\n * @param {number} startTime This argument is start time [sec] on `AudioBuffer`.\n * @param {number} endTime This argument is end time [sec] on `AudioBuffer`.\n * @return {AudioBuffer} This is returned as sliced `AudioBuffer`.\n */\n slice(startTime, endTime) {\n if (!this.isBuffer()) {\n return null;\n }\n\n const {\n sampleRate,\n length,\n numberOfChannels\n } = this.buffer;\n\n let start = Math.floor(startTime * sampleRate);\n let end = Math.floor(endTime * sampleRate);\n\n if (isNaN(start) || (start < 0)) {\n start = 0;\n }\n\n if (isNaN(end) || (end > length)) {\n end = length;\n }\n\n let dataLs = null;\n let dataRs = null;\n\n if (numberOfChannels > 0) {\n dataLs = this.buffer.getChannelData(0);\n }\n\n if (numberOfChannels > 1) {\n dataRs = this.buffer.getChannelData(1);\n }\n\n let bufferLs = null;\n let bufferRs = null;\n let buffer = null;\n\n const bufferSize = end - start;\n\n switch (numberOfChannels) {\n case 1:\n bufferLs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n }\n\n buffer = this.context.createBuffer(1, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n\n return buffer;\n case 2:\n bufferLs = new Float32Array(bufferSize);\n bufferRs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n bufferRs[i - start] = dataRs[i];\n }\n\n buffer = this.context.createBuffer(2, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n buffer.copyToChannel(bufferRs, 1);\n\n return buffer;\n default:\n return null;\n }\n }\n\n /**\n * This method sprites audio.\n * @param {object} sprites This argument is the associative array that contains sprite times.\n * @return {object} This is returned as the associative array that contains sprited `AudioBuffer`.\n */\n sprite(sprites) {\n if (!this.isBuffer()) {\n return null;\n }\n\n if (Object.prototype.toString.call(sprites) !== '[object Object]') {\n return null;\n }\n\n return Object.keys(sprites).reduce((audioBuffers, key) => {\n const times = sprites[key];\n\n if (!Array.isArray(times) || (times.length !== 2)) {\n return audioBuffers;\n }\n\n audioBuffers[key] = this.slice(parseFloat(times[0]), parseFloat(times[1]));\n\n return audioBuffers;\n }, {});\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.audio = {\n 'playbackrate' : this.isSource() ? this.source.playbackRate.value : 1,\n 'vocalcanceler' : {\n 'depth' : this.vocalcanceler.param('depth')\n }\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[AudioModule]';\n }\n}\n","'use strict';\n\nimport { AudioModule } from '../AudioModule';\n\n/**\n * This class defines properties for processing sound data from `HTMLMediaElement`.\n * Namely, this class creates audio player that has higher features from `HTMLMediaElement`.\n * But, this class is disadvantage to play the many one shot audios.\n * In the case of that, developer should use `OneshotModule`.\n * @constructor\n * @extends {AudioModule}\n */\nexport class MediaModule extends AudioModule {\n static AUDIO = 'audio';\n static VIDEO = 'video';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.source = null; // for the instance of `MediaElementAudioSourceNode`\n this.media = null; // for the instance of `HTMLMediaElement`\n this.ext = ''; // 'wav', 'ogg', 'mp3, 'webm', 'ogv', 'mp4' ...etc\n\n // for Audio Streaming\n this.mse = null; // for the instance of `MediaSource`\n this.sb = null; // for the instance of `SourceBuffer`\n this.file = '';\n this.mimeType = '';\n\n this.playbackRate = 1;\n this.controls = false;\n this.loop = false;\n this.muted = false;\n this.autoplay = false;\n\n // The keys are the event interfaces that are defined by `HTMLMediaElement` or `MediaSource` or `SourceBuffer`.\n // For example, `loadstart`, `loadedmetadata`, `loadeddata`, `canplay`, `canplaythrough`, `timeupdate`, `ended`,\n // `sourceopen`, `sourceended`, `sourceclose`, `updateend`, `error` ... etc\n this.listeners = {};\n }\n\n /**\n * This method gets `HTMLMediaElement` and selects media format. In addition, this method adds event listeners that are defined by `HTMLMediaElement`.\n * @param {HTMLAudioElement|HTMLVideoElement} media This argument is either `HTMLAudioElement` or `HTMLVideoElement`.\n * @param {Array.<string>|string} formats This argument is usable media format. For example, 'wav', 'ogg', 'webm', 'mp4' ...etc.\n * @param {object} listeners This argument is event handlers that are defined by `HTMLMediaElement`.\n * @param {boolean} autoplay This argument is in order to determine autoplay. The default value is `false`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n setup(media, formats, listeners, autoplay) {\n this.envelopegenerator.setGenerator(0);\n this.envelopegenerator.param({\n 'attack' : 0,\n 'decay' : 0.01,\n 'sustain' : 1,\n 'release' : 0.01\n });\n\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('media' in properties) {\n media = properties.media;\n }\n\n if ('formats' in properties) {\n formats = properties.formats;\n }\n\n if ('listeners' in properties) {\n listeners = properties.listeners;\n }\n\n if ('autoplay' in properties) {\n autoplay = properties.autoplay;\n }\n }\n\n let type = '';\n\n if (media instanceof HTMLAudioElement) {\n type = MediaModule.AUDIO;\n } else if (media instanceof HTMLVideoElement) {\n type = MediaModule.VIDEO;\n } else {\n return this;\n }\n\n this.media = media;\n\n if (!Array.isArray(formats)) {\n formats = [formats];\n }\n\n for (const format of formats) {\n const f = `${type}/${String(format).toLowerCase()}`;\n\n if (/^(?:maybe|probably)/.test(this.media.canPlayType(f))) {\n this.ext = format;\n break;\n }\n }\n\n if (Object.prototype.toString.call(listeners) === '[object Object]') {\n for (const k in listeners) {\n this.listeners[k.toLowerCase()] = (Object.prototype.toString.call(listeners[k]) === '[object Function]') ? listeners[k] : () => {};\n }\n }\n\n this.autoplay = Boolean(autoplay);\n\n // in the case of autoplay, `loadstart` event not fire\n if (this.autoplay && !(this.source instanceof MediaElementAudioSourceNode)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n\n if (this.autoplay && this.media.src) {\n this.context.resume()\n .then(() => {\n this.start(this.media.currentTime);\n })\n .catch(() => {\n throw new Error('Autoplay is failed');\n });\n }\n\n this.media.addEventListener('loadstart', event => {\n // To create the instance of `MediaElementAudioSourceNode` again causes error to occur\n if (!(this.source instanceof MediaElementAudioSourceNode)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n\n if ('loadstart' in this.listeners) {\n this.listeners.loadstart(event);\n }\n }, false);\n\n this.media.addEventListener('ended', event => {\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n if ('ended' in this.listeners) {\n this.listeners.ended(event);\n }\n }, false);\n\n for (const k in this.listeners) {\n this.media.addEventListener(k, event => {\n this.listeners[(event.type).toLowerCase()](event);\n }, false);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|boolean|MediaModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let r;\n\n if (k === 'mastervolume') {\n r = super.param(k, value);\n }\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'playbackrate':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media.playbackRate : this.playbackRate;\n }\n\n v = parseFloat(value);\n min = 0.5; // for Chrome\n\n if (v >= min) {\n if (this.media instanceof HTMLMediaElement) {\n this.media.playbackRate = v;\n }\n\n this.playbackRate = v;\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / v)), true);\n }\n }\n\n break;\n case 'currenttime':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media.currentTime : 0;\n }\n\n if (this.media instanceof HTMLMediaElement) {\n v = parseFloat(value);\n min = 0;\n max = this.media.duration;\n\n if ((v >= min) && (v <= max)) {\n this.media.currentTime = v;\n\n const startTime = this.context.currentTime;\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - v) / playbackRate)), true);\n }\n }\n }\n\n break;\n case 'loop' :\n case 'muted' :\n case 'controls':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media[k] : this[k];\n }\n\n if (this.media instanceof HTMLMediaElement) {\n this.media[k] = Boolean(value);\n }\n\n this[k] = Boolean(value);\n\n break;\n case 'width' :\n case 'height':\n if (value === undefined) {\n return (this.media instanceof HTMLVideoElement) ? this.media[k] : 0;\n }\n\n v = parseInt(value, 10);\n min = 0;\n\n if (v >= min) {\n if (this.media instanceof HTMLVideoElement) {\n this.media[k] = v;\n }\n }\n\n break;\n case 'duration':\n return this.media && this.media.duration ? this.media.duration : 0; // Getter only\n case 'channels':\n return (this.source instanceof MediaElementAudioSourceNode) ? this.source.channelCount : 0; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method prepares for playing the media anytime after loading the media resource.\n * @param {string} source This argument is path name or `Data URL` or `Object URL` for the media resource.\n * @param {string} mimeType This argument is required in the case of audio streaming.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n ready(source, mimeType) {\n const src = String(source);\n\n if (this.mse && (this.mse.readyState === 'open')) {\n this.mse.endOfStream();\n window.URL.revokeObjectURL(this.media.src);\n\n this.mse.removeEventListener('sourceopen', this.onSourceOpen, false);\n this.mse.removeEventListener('sourceended', this.onSourceEnded, false);\n this.mse.removeEventListener('sourceclose', this.onSourceClose, false);\n\n this.sb.removeEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sb.removeEventListener('error', this.onSourceBufferError, false);\n }\n\n try {\n if (mimeType) {\n // Audio Streaming\n if (!MediaSource || !MediaSource.isTypeSupported(mimeType)) {\n throw new Error('This Browser does not support `MediaSource` or MIME type');\n }\n\n this.media.removeAttribute('src');\n\n this.media.load();\n\n this.mse = new MediaSource();\n this.media.src = window.URL.createObjectURL(this.mse);\n this.mimeType = mimeType;\n this.file = src;\n\n this.onSourceOpen = this.onSourceOpen.bind(this);\n this.onSourceEnded = this.onSourceEnded.bind(this);\n this.onSourceClose = this.onSourceClose.bind(this);\n\n this.mse.addEventListener('sourceopen', this.onSourceOpen, false);\n this.mse.addEventListener('sourceended', this.onSourceEnded, false);\n this.mse.addEventListener('sourceclose', this.onSourceClose, false);\n } else if ((src.indexOf('data:') !== -1) || (src.indexOf('blob:') !== -1) || (this.ext === '')) {\n // `Data URL` or `Object URL` or Full path\n this.media.src = src;\n } else {\n // Path\n this.media.src = `${src}.${this.ext}`;\n }\n } catch (error) {\n throw new Error(error.message);\n }\n\n return this;\n }\n\n /**\n * This method starts media from the designated time.\n * @param {number} position This argument is the time that media is started at. The default value is 0.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n start(position, connects, processCallback) {\n if (this.source instanceof MediaElementAudioSourceNode) {\n // MediaElementAudioSourceNode (Input) -> GainNode (Envelope Generator) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor, connects);\n\n const promise = this.media.play();\n\n promise.then(() => {\n const startTime = this.context.currentTime;\n\n const pos = parseFloat(position);\n\n this.media.currentTime = ((pos >= 0) && (pos <= this.media.duration)) ? pos : 0;\n this.media.playbackRate = this.playbackRate;\n this.media.controls = this.controls;\n this.media.loop = this.loop;\n this.media.muted = this.muted;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(this.media.duration)) {\n this.envelopegenerator.stop((startTime + ((this.media.duration - pos) / this.media.playbackRate)), true);\n }\n\n this.on(startTime);\n\n this.analyser.start('time');\n this.analyser.start('fft');\n\n const bufferSize = this.processor.bufferSize;\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.vocalcanceler.start(inputLs[i], inputRs[i]);\n outputRs[i] = this.vocalcanceler.start(inputRs[i], inputLs[i]);\n }\n };\n }\n }).catch(() => {\n this.stop(() => {\n if (this.autoplay) {\n this.media.muted = this.muted = true;\n this.media.volume = 0;\n }\n\n this.start(position, connects, processCallback);\n }, () => {\n });\n });\n }\n\n return this;\n }\n\n /**\n * This method stops media.\n * @param {function} successCallback This argument is invoked when `HTMLMediaElement#play` is successful.\n * @param {function} errorCallback This argument is invoked when `HTMLMediaElement#play` is failure.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n stop(successCallback, errorCallback) {\n if (this.source instanceof MediaElementAudioSourceNode) {\n // ref: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted\n this.media.play()\n .then(() => {\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback();\n }\n\n return Promise.resolve();\n })\n .catch(error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error);\n }\n\n return Promise.reject(error);\n });\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `MediaElementAudioSourceNode`.\n * @return {MediaElementAudioSourceNode}\n * @override\n */\n get() {\n return this.source;\n }\n\n /**\n * This method starts or stops media according to media state.\n * @param {number} position This argument is time that media is started at.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n toggle(position, connects, processCallback) {\n if (this.media.paused) {\n this.start(position, connects, processCallback);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method determines whether the instance of `HTMLMediaElement` exists.\n * @return {boolean} If the instance of `HTMLMediaElement` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isMedia() {\n return this.media instanceof HTMLMediaElement;\n }\n\n /**\n * This method determines whether the instance of `MediaElementAudioSourceNode` exists.\n * @return {boolean} If the instance of `MediaElementAudioSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n * @override\n */\n isSource() {\n return this.source instanceof MediaElementAudioSourceNode;\n }\n\n /**\n * This method determines whether the media is paused.\n * @return {boolean} If the media is paused or does not exists, this value is `true`. Otherwise, this value is `false`.\n * @override\n */\n isPaused() {\n return (this.media instanceof HTMLMediaElement) ? this.media.paused : true;\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceOpen(event) {\n this.sb = this.mse.addSourceBuffer(this.mimeType);\n\n this.sb.mode = 'sequence';\n\n this.onSourceBufferUpdateEnd = this.onSourceBufferUpdateEnd.bind(this);\n this.onSourceBufferError = this.onSourceBufferError.bind(this);\n\n this.sb.addEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sb.addEventListener('error', this.onSourceBufferError, false);\n\n if ('sourceopen' in this.listeners) {\n this.listeners.sourceopen(event);\n }\n\n const request = new Request(this.file);\n\n fetch(request)\n .then(response => {\n return response.arrayBuffer();\n })\n .then(data => {\n this.sb.appendBuffer(data);\n })\n .catch(error => {\n if ('error' in this.listeners) {\n this.listeners.error(event, error);\n }\n });\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceEnded(event) {\n if ('sourceended' in this.listeners) {\n this.listeners.sourceended(event);\n }\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceClose(event) {\n if ('sourceclose' in this.listeners) {\n this.listeners.sourceclose(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceBufferUpdateEnd(event) {\n if ('updateend' in this.listeners) {\n this.listeners.updateend(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceBufferError(event) {\n if ('error' in this.listeners) {\n this.listeners.error(event);\n }\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.media = {\n 'playbackrate' : this.playbackRate,\n 'vocalcanceler' : {\n 'depth' : this.vocalcanceler.param('depth')\n }\n };\n\n delete params.audio;\n\n return params;\n }\n\n /**\n * This method requests Picture In Picture (PIP).\n * @return {Promise} This is returned as `Promise`.\n */\n requestPictureInPicture() {\n if (!(this.media instanceof HTMLVideoElement)) {\n return Promise.reject();\n }\n\n if (!('pictureInPictureEnabled' in document)) {\n return Promise.reject();\n }\n\n if (!document.pictureInPictureEnabled) {\n return Promise.reject();\n }\n\n if (this.media.disablePictureInPicture) {\n return Promise.reject();\n }\n\n if (this.media.readyState === 0) {\n return Promise.reject();\n }\n\n if (this.media === document.pictureInPictureElement) {\n return Promise.reject();\n }\n\n return this.media.requestPictureInPicture();\n }\n\n /**\n * This method exits from Picture In Picture (PIP).\n * @return {Promise} This is returned as `Promise`.\n */\n exitPictureInPicture() {\n if (!(this.media instanceof HTMLVideoElement)) {\n return Promise.reject();\n }\n\n if (!('pictureInPictureEnabled' in document)) {\n return Promise.reject();\n }\n\n if (!document.pictureInPictureEnabled) {\n return Promise.reject();\n }\n\n if (this.media.disablePictureInPicture) {\n return Promise.reject();\n }\n\n if (this.media.readyState === 0) {\n return Promise.reject();\n }\n\n if (this.media !== document.pictureInPictureElement) {\n return Promise.reject();\n }\n\n return document.exitPictureInPicture();\n }\n\n /** @override */\n toString() {\n return '[MediaModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Noise Gate.\n * @constructor\n */\nexport class NoiseGate {\n constructor() {\n this.level = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|NoiseGate} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'level':\n if (value === undefined) {\n return this.level;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.level = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method detects background noise and removes this.\n * @param {number} data This argument is amplitude (between -1 and 1).\n * @return {number} This is returned as 0 or the raw data.\n */\n start(data) {\n const d = Math.abs(parseFloat(data));\n\n // data : The amplitude is equal to argument.\n // 0 : Because signal is detected as background noise, the amplitude is 0.\n return (d > this.level) ? data : 0;\n }\n\n /** @override */\n toString() {\n return '[StreamModule NoiseGate]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for NoiseSuppressor.\n * @constructor\n */\nexport class NoiseSuppressor {\n /**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\n static FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n }\n\n /**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\n static IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n }\n\n /** @constructor */\n constructor() {\n this.threshold = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|NoiseSuppressor} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'threshold':\n if (value === undefined) {\n return this.threshold;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.threshold = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method detects background noise and removes this.\n * @param {Float32Array} inputs This argument is the instance of `Float32Array` for `ScriptProcessorNode`.\n * @param {Float32Array} outpus This argument is the instance of `Float32Array` for `ScriptProcessorNode`.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @return {NoiseSuppressor} This is returned for method chain.\n */\n start(inputs, outputs, bufferSize) {\n if (this.threshold > 0) {\n const xreals = new Float32Array(inputs);\n const ximags = new Float32Array(bufferSize);\n\n const yreals = new Float32Array(bufferSize);\n const yimags = new Float32Array(bufferSize);\n\n const amplitudes = new Float32Array(bufferSize);\n const phases = new Float32Array(bufferSize);\n\n NoiseSuppressor.FFT(xreals, ximags, bufferSize);\n\n for (let k = 0; k < bufferSize; k++) {\n amplitudes[k] = Math.sqrt(Math.pow(xreals[k], 2) + Math.pow(ximags[k], 2));\n\n if ((xreals[k] !== 0) && (ximags[k] !== 0)) {\n phases[k] = Math.atan2(ximags[k], xreals[k]);\n }\n\n amplitudes[k] -= this.threshold;\n\n if (amplitudes[k] < 0) {\n amplitudes[k] = 0;\n }\n\n yreals[k] = amplitudes[k] * Math.cos(phases[k]);\n yimags[k] = amplitudes[k] * Math.sin(phases[k]);\n }\n\n NoiseSuppressor.IFFT(yreals, yimags, bufferSize);\n\n outputs.set(yreals);\n } else {\n outputs.set(inputs);\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[StreamModule NoiseSuppressor]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { NoiseGate } from './NoiseGate';\nimport { NoiseSuppressor } from './NoiseSuppressor';\n\n/**\n * This class defines properties that processes sound data from WebRTC in Web Audio API.\n * @constructor\n * @extends {SoundModule}\n */\nexport class StreamModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.sources = []; /** @type {Array.<MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode>} */\n\n this.stream = null; // for the instance of `MediaStream`\n\n // for `navigator.mediaDevices.getUserMedia`\n this.constraints = {\n 'audio' : true,\n 'video' : false\n };\n\n this.callbacks = {\n 'stream' : () => {},\n 'error' : () => {}\n };\n\n this.each = false;\n this.output = true;\n\n this.isStop = true;\n\n this.noisegate = new NoiseGate();\n this.noisesuppressor = new NoiseSuppressor();\n }\n\n /**\n * This method sets up for using WebRTC.\n * @param {object} constraints This argument is the 1st argument for `getUserMedia`.\n * @param {function} streamCallback This argument is invoked on streaming.\n * @param {function} errorCallback This argument is invoked when error occurs on streaming.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n setup(constraints, streamCallback, errorCallback) {\n if (Object.prototype.toString.call(constraints) === '[object Object]') {\n this.constraints = constraints;\n }\n\n if (Object.prototype.toString.call(streamCallback) === '[object Function]') {\n this.callbacks.stream = streamCallback;\n }\n\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n this.callbacks.error = errorCallback;\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|boolean|StreamModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n switch (k) {\n case 'each':\n if (value === undefined) {\n return this.each;\n }\n\n this.each = Boolean(value);\n\n break;\n case 'output':\n if (value === undefined) {\n return this.output;\n }\n\n this.output = Boolean(value);\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method opens devices or sets the instance of `MediaStream`.\n * @param {MediaStream} stream This argument is the instance of `MediaStream`.\n * @return {Promise} This is returned as `Promise` of `getUserMedia`.\n * @override\n */\n ready(stream) {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia || !window.MediaStream) {\n return Promise.reject('Cannot use WebRTC.');\n }\n\n this.isStop = false;\n\n if (stream instanceof MediaStream) {\n this.stream = stream;\n return Promise.resolve();\n }\n\n return navigator.mediaDevices.getUserMedia(this.constraints)\n .then(stream => {\n if (this.isStop) {\n return;\n }\n\n this.stream = stream;\n\n this.callbacks.stream(stream);\n }).catch(error => {\n this.callbacks.error(error);\n });\n }\n\n /**\n * This method starts streaming.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Promise} This is returned as `Promise` of `getUserMedia`.\n * @override\n */\n start(connects, processCallback) {\n if (this.stream === null) {\n return this;\n }\n\n const bufferSize = this.processor.bufferSize;\n\n let runAnalyser = false;\n\n if (this.each) {\n // Get the instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (let i = 0, len = audioTracks.length; i < len; i++) {\n this.sources[i] = this.context.createMediaStreamTrackSource(audioTracks[i]);\n\n // MediaStreamTrackAudioSourceNode (Input) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.sources[i].connect(this.processor);\n this.connect(this.processor, connects);\n }\n } else {\n this.sources[0] = this.context.createMediaStreamSource(this.stream);\n\n // MediaStreamAudioSourceNode (Input) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.sources[0].connect(this.processor);\n this.connect(this.processor, connects);\n }\n\n if (!this.output) {\n this.mastervolume.disconnect(0);\n\n // for analyser\n this.mastervolume.connect(this.analyser.input);\n\n // for recording\n this.mastervolume.connect(this.recorder.processor);\n this.recorder.processor.connect(this.context.destination);\n\n // for session\n this.mastervolume.connect(this.session.sender);\n this.session.sender.connect(this.context.destination);\n }\n\n this.on(this.context.currentTime);\n\n if (!runAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n runAnalyser = true;\n }\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.noisegate.start(inputLs[i]);\n outputRs[i] = this.noisegate.start(inputRs[i]);\n }\n\n this.noisesuppressor.start(inputLs, outputLs, bufferSize);\n this.noisesuppressor.start(inputRs, outputRs, bufferSize);\n };\n }\n\n return this;\n }\n\n /**\n * This method stops streaming.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n stop() {\n this.sources.length = 0;\n\n this.off(this.context.currentTime, true);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.isStop = true;\n\n return this;\n }\n\n /**\n * This method gets the instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode`.\n * @param {number} index This argument is required in the case of designating track.\n * @return {MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode|Array.<MediaStreamTrackAudioSourceNode>}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /**\n * This method gets the instance of `MediaStream`.\n * @return {MediaStream}\n * @override\n */\n getStream() {\n return this.stream;\n }\n\n /**\n * This method starts or stops streaming according to current state.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {StreamModule} This is returned for method chain.\n */\n toggle(connects, processCallback) {\n if (this.isStreaming()) {\n this.stop();\n } else {\n this.start(connects, processCallback);\n }\n\n return this;\n }\n\n /**\n * This method stops microphone and camera by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clear() {\n this.stop();\n\n this.clearAudio();\n this.clearVideo();\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clearAudio() {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get the instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (const audioTrack of audioTracks) {\n audioTrack.stop();\n }\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clearVideo() {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get the instance of `MediaStreamTrack` for video\n const videoTracks = this.stream.getVideoTracks();\n\n for (const videoTrack of videoTracks) {\n videoTrack.stop();\n }\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method gets available devices as array that contains the instances of `MediaDeviceInfo`.\n * @return {Promise} This is returned as `Promise` of `enumerateDevices`.\n */\n devices() {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return Promise.reject('No devices.');\n }\n\n return navigator.mediaDevices.enumerateDevices();\n }\n\n /**\n * This method determines whether streaming is active.\n * @return {boolean} If streaming is active, this value is `true`. Otherwise, this value is `false`.\n */\n isStreaming() {\n return !this.isStop;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.stream = {\n 'output' : this.output,\n 'noisegate' : { 'level' : this.noisegate.param('level') },\n 'noisesuppressor' : { 'threshold' : this.noisesuppressor.param('threshold') }\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[StreamModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { AudioModule } from '../AudioModule';\nimport { MediaModule } from '../MediaModule';\nimport { StreamModule } from '../StreamModule';\n\n/**\n * This class defines properties for mixing sound sources that is defined in this library.\n * @constructor\n * @extends {SoundModule}\n */\nexport class MixerModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n /** @type {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>} */\n this.sources = [];\n\n this.isAnalyser = false;\n }\n\n /**\n * This method mixes sound source.\n * @param {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>} sources This argument is the array of sound source that is defined by this library.\n * @return {MixerModule} This is returned for method chain.\n */\n mix(sources) {\n if (!Array.isArray(sources)) {\n sources = [sources];\n }\n\n this.sources = sources;\n\n for (const source of this.sources) {\n if (!((source instanceof OscillatorModule) || (source instanceof OneshotModule) || (source instanceof AudioModule) || (source instanceof MediaModule) || (source instanceof StreamModule))) {\n return this;\n }\n\n const stopTime = this.context.currentTime;\n\n this.off(stopTime, false);\n\n source.analyser.stop('time');\n source.analyser.stop('fft');\n source.isAnalyser = false;\n\n source.recorder.stop();\n source.session.close();\n\n // ScriptProcessorNode (each sound source) -> ScriptProcessorNode (Mix sound sources)\n source.processor.disconnect(0);\n source.processor.connect(this.processor);\n }\n\n // (... ->) ScriptProcessorNode (Mix sound sources) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n\n const startTime = this.context.currentTime;\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n // Stop ?\n let isStop = false;\n\n for (const source of sources) {\n if ((source instanceof OscillatorModule) && source.envelopegenerator.isStop()) {\n isStop = true;\n } else if ((source instanceof OneshotModule) && source.isStop) {\n isStop = true;\n } else if ((source instanceof AudioModule) && source.paused) {\n isStop = true;\n } else if ((source instanceof MediaModule) && source.media.paused) {\n isStop = true;\n } else if ((source instanceof StreamModule) && source.isStop) {\n isStop = true;\n }\n }\n\n if (isStop) {\n const stopTime = this.context.currentTime;\n\n this.on(stopTime, true);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n\n return this;\n }\n\n /**\n * This method gets the instance of sound source that is mixed in this class.\n * @param {number} index This argument is required in the case of designating sound source.\n * @return {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>|OscillatorModule|OneshotModule|AudioModule|MediaModule|StreamModule}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /** @override */\n toString() {\n return '[MixerModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\nexport class ProcessorModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.envelopegenerator.setGenerator(0);\n\n this.processor = null;\n this.name = '';\n this.options = {};\n this.moduleURL = '';\n this.promise = null;\n this.map = null; // Polyfill for `AudioParamMap`\n\n this.runAnalyser = false;\n }\n\n /**\n * This method sets registered processor and options for `AudioWorkletNode` constructor.\n * @param {string} name This argument is the name of the `AudioWorkletProcessor` this node will be based on.\n * @param {object} options This argument is an object based on the `AudioWorkletNodeOptions` dictionary.\n * @return {ProcessorModule} This is returned for method chain.\n * @override\n */\n setup(name, options) {\n this.name = String(name);\n\n if (Object.prototype.toString.call(options) === '[object Object]') {\n this.options = options;\n }\n\n if (!window.AudioWorkletNode) {\n // Polyfill\n this.processor = this.context.createScriptProcessor(this.bufferSize, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n this.map = new Map();\n }\n\n return this;\n }\n\n /**\n * This method adds module for worklet and creates the instance of `AudioWorkletNode`.\n * @param {string} moduleURL This argument is the string containing the URL of a JavaScript file with the module to add.\n * @param {object} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise} This is returned as `Promise` of `addModule`.\n * @override\n */\n ready(moduleURL, options) {\n if (!window.AudioWorkletNode) {\n return Promise.reject('Cannot use AudioWorklet');\n }\n\n this.moduleURL = String(moduleURL);\n\n if (Object.prototype.toString.call(options) === '[object Object]') {\n this.promise = this.context.audioWorklet.addModule(this.moduleURL, options);\n } else {\n this.promise = this.context.audioWorklet.addModule(this.moduleURL);\n }\n\n return this.promise\n .then(() => {\n if (Object.keys(this.options).length > 0) {\n this.processor = new AudioWorkletNode(this.context, this.name, this.options);\n } else {\n this.processor = new AudioWorkletNode(this.context, this.name);\n }\n });\n }\n\n /**\n * This method starts sound by connecting to `AudioDestinationNode`.\n * @param {function} processCallback This argument is in order to set `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @return {ProcessorModule} This is returned as method chain.\n * @override\n */\n start(processCallback, connects) {\n const startTime = this.context.currentTime;\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n\n if (this.processor.onaudioprocess instanceof ScriptProcessorNode) {\n this.processor.onaudioprocess = null;\n }\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(this.envelopegenerator.getGenerator(0), connects);\n\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.runAnalyser = true;\n }\n\n this.on(startTime);\n\n if ((this.processor instanceof ScriptProcessorNode) && (Object.prototype.toString.call(processCallback) === '[object Function]')) {\n this.processor.onaudioprocess = processCallback;\n }\n\n return this;\n }\n\n /**\n * This method stops sound by disconnecting to `AudioDestinationNode`.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {ProcessorModule} This is returned for method chain.\n * @override\n */\n stop(processCallback) {\n const stopTime = this.context.currentTime;\n\n this.processor.disconnect(0);\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n if ((this.processor instanceof ScriptProcessorNode) && (Object.prototype.toString.call(processCallback) === '[object Function]')) {\n this.processor.onaudioprocess = processCallback;\n }\n\n return this;\n }\n\n /**\n * This method sends a message from the `MessagePort` of `AudioWorkletNode`.\n * @param {any} data This argument is sent as any data.\n * @return {ProcessorModule} This is returned for method chain.\n */\n postMessage(data) {\n if (this.processor instanceof AudioWorkletNode) {\n this.processor.port.postMessage(data);\n }\n\n return this;\n }\n\n /**\n * This method sets the event handler that is invoked when the port receives a message.\n * @param {function} This argument is invoked when the port receives a message.\n * @return {ProcessorModule} This is returned for method chain.\n */\n onMessage(callback) {\n if (this.processor instanceof AudioWorkletNode) {\n if ((Object.prototype.toString.call(callback) === '[object Function]') || (callback === null)) {\n this.processor.port.onmessage = callback;\n }\n }\n\n return this;\n }\n\n /**\n * This method sets the event handler that is invoked when it receives a message that cannot be deserialized.\n * @param {function} This argument is invoked when it receives a message that cannot be deserialized.\n * @return {ProcessorModule} This is returned for method chain.\n */\n onMessageError(callback) {\n if (this.processor instanceof AudioWorkletNode) {\n if ((Object.prototype.toString.call(callback) === '[object Function]') || (callback === null)) {\n this.processor.port.onmessageerror = callback;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets object that is accessed as a `AudioParamMap`.\n * @return {AudioParamMap|Map} This is returned as `AudioParamMap` (or empty `Map`).\n */\n map() {\n if (this.processor instanceof AudioWorkletNode) {\n return this.processor.parameters;\n }\n\n return this.map;\n }\n\n /**\n * This method gets the instance of `AudioParam` that is defined by `AudioParamDescriptor`.\n * @param {string} This argument is the key for getting as `AudioParam`.\n * @return {AudioParam} This is returned as `AudioParam`.\n */\n param(key) {\n if (this.processor instanceof AudioWorkletNode) {\n return this.processor.parameters.get(key);\n }\n\n return null;\n }\n\n /**\n * This method gets the instance of `AudioWorkletNode` (or `ScriptProcessorNode`).\n * @return {AudioWorkletNode|ScriptProcessorNode}\n * @override\n */\n get() {\n return this.processor;\n }\n\n /** @override */\n toString() {\n return '[ProcessorModule]';\n }\n}\n","'use strict';\n\n/**\n * This class defines properties for using Web MIDI API.\n * @constructor\n */\nexport class MIDI {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.midiAccess = null; // for the instance of `MIDIAccess`\n this.inputs = []; // for the instances of `MIDIInput`\n this.outputs = []; // for the instances of `MIDIOutput`\n }\n\n /**\n * This method invokes `requestMIDIAccess` and gets objects for using Web MIDI API.\n * @param {boolean} sysex This argument is in order to select whether using system exclusive message.\n * @param {function} successCallback This argument is invoked when `requestMIDIAccess` succeeds.\n * @param {function} errorCallback This argument is invoked when `requestMIDIAccess` fails.\n * @return {MIDI} This is returned for method chain.\n */\n setup(sysex, successCallback, errorCallback) {\n if (!navigator.requestMIDIAccess) {\n throw new Error('Cannot use Web MIDI API.');\n }\n\n navigator.requestMIDIAccess({ sysex : Boolean(sysex) }).then(midiAccess => {\n this.midiAccess = midiAccess;\n\n if (Object.prototype.toString.call(midiAccess) === '[object Function]') {\n // Legacy Chrome\n this.inputs = midiAccess.inputs();\n this.outputs = midiAccess.outputs();\n } else {\n // Chrome 39 and later\n const inputIterator = midiAccess.inputs.values();\n const outputIterator = midiAccess.outputs.values();\n\n for (let i = inputIterator.next(); !i.done; i = inputIterator.next()) {\n this.inputs.push(i.value);\n }\n\n for (let o = outputIterator.next(); !o.done; o = outputIterator.next()) {\n this.outputs.push(o.value);\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(this.midiAccess, this.inputs, this.outputs);\n }\n }).catch(error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error);\n }\n });\n\n return this;\n }\n\n /**\n * This method gets the instance of `MIDIAccess`.\n * @return {MIDIAccess}\n */\n get() {\n return this.midiAccess;\n }\n\n /** @override */\n toString() {\n return '[MIDI]';\n }\n}\n","'use strict';\n\n/**\n * MML characters are corresponds to tokens by this map.\n * Namely, this map is definitions of MML Tokens.\n */\nexport const TokenMap = new Map([\n ['T', 'TEMPO'],\n ['O', 'OCTAVE'],\n ['C', 'NOTE'],\n ['D', 'NOTE'],\n ['E', 'NOTE'],\n ['F', 'NOTE'],\n ['G', 'NOTE'],\n ['A', 'NOTE'],\n ['B', 'NOTE'],\n ['+', 'NOTE'],\n ['-', 'NOTE'],\n ['#', 'NOTE'],\n ['R', 'REST'],\n ['0', 'NUMBER'],\n ['1', 'NUMBER'],\n ['2', 'NUMBER'],\n ['3', 'NUMBER'],\n ['4', 'NUMBER'],\n ['5', 'NUMBER'],\n ['6', 'NUMBER'],\n ['7', 'NUMBER'],\n ['8', 'NUMBER'],\n ['9', 'NUMBER'],\n ['.', 'NUMBER'],\n ['&', 'TIE'],\n [' ', 'SPACE'],\n [undefined, 'EOS']\n]);\n\n/**\n * This is enumeration types for MML Tokens.\n */\nexport const TokenTypes = {\n 'TEMPO' : 1,\n 'OCTAVE' : 2,\n 'NOTE' : 3,\n 'REST' : 4,\n 'NUMBER' : 5,\n 'TIE' : 6,\n 'SPACE' : 7,\n 'EOS' : 8,\n 'UNKNOWN': 9\n};\n\n/**\n * This class has token type, token data and token value if token is number.\n * @constructor\n */\nexport class Token {\n /**\n * @param {TokenTypes} type This argument is the one of enumeration values that is defined by `TokenTypes`.\n * @param {string} token This argument is a string that constructs of token.\n */\n constructor(type, token) {\n this.type = type;\n this.token = token;\n this.value = parseInt(token, 10);\n }\n\n /**\n * This method is getter for token type.\n */\n getType() {\n return this.type || null;\n }\n\n /**\n * This method is getter for token.\n */\n getToken() {\n return this.token;\n }\n\n /**\n * This method is getter for token value if token is number.\n */\n getValue() {\n return isNaN(this.value) ? null : this.value;\n }\n}\n","'use strict';\n\nimport { TokenMap, TokenTypes, Token } from './Token';\n\n/**\n * This class is Tokenization for MML (Music Macro Language).\n * @constructor\n */\nexport class Tokenizer {\n /**\n * @param {string} mml This argument is MML string.\n */\n constructor(mml) {\n if (typeof mml === 'string') {\n // `reverse` for getting token by `pop`\n this.tokens = mml.trim().toUpperCase().split('').reverse();\n } else {\n this.tokens = [];\n }\n\n this.notes = [];\n this.numbers = [];\n }\n\n /**\n * This method executes tokenization from MML.\n * @return {Token} This is returned as the instance of `Token`.\n */\n get() {\n let token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.SPACE) {\n token = this.tokens.pop();\n }\n\n if (TokenTypes[TokenMap.get(token)] === TokenTypes.EOS) {\n return new Token(TokenTypes.EOS, token);\n }\n\n this.notes.length = 0;\n this.numbers.length = 0;\n\n switch (TokenTypes[TokenMap.get(token)]) {\n case TokenTypes.TEMPO:\n return new Token(TokenTypes.TEMPO, token);\n case TokenTypes.OCTAVE:\n return new Token(TokenTypes.OCTAVE, token);\n case TokenTypes.NOTE:\n this.notes.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.NOTE) {\n this.notes.push(token);\n\n token = this.tokens.pop();\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(TokenTypes.NOTE, this.notes.join(''));\n case TokenTypes.REST:\n return new Token(TokenTypes.REST, token);\n case TokenTypes.NUMBER:\n this.numbers.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.NUMBER) {\n this.numbers.push(token);\n\n token = this.tokens.pop();\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(TokenTypes.NUMBER, this.numbers.join(''));\n case TokenTypes.TIE:\n return new Token(TokenTypes.TIE, token);\n default:\n return new Token(TokenTypes.UNKNOWN, token);\n }\n }\n}\n","'use strict';\n\n/**\n * This class is structure for Tree Construction.\n * @constructor\n */\nexport class Tree {\n static indent = 0;\n\n /**\n * @param {Token} operator This argument is the instance of `Token` as Tree Node.\n * @param {Tree} left This argument is the instance of `Tree` as left partial tree.\n * @param {Tree} right This argument is the instance of `Tree` as right partial tree.\n */\n constructor(operator, left, right) {\n this.operator = operator;\n this.left = left;\n this.right = right;\n }\n\n /**\n * This method concatenates partial tree as right partial tree.\n * @param {Token} operator This argument is the instance of `Token` as Tree Node.\n */\n concat(node) {\n this.right = node;\n }\n\n /**\n * This method is getter for operator.\n */\n getOperator() {\n return this.operator;\n }\n\n /**\n * This method is getter for left partial tree\n */\n getLeft() {\n return this.left;\n }\n\n /**\n * This method is getter for right partial tree\n */\n getRight() {\n return this.right;\n }\n\n /** @override */\n toString() {\n let space = '';\n\n for (let i = 0; i < Tree.indent; i++) {\n space += ' ';\n }\n\n Tree.indent++;\n\n // Return syntax tree string\n return `\n ${space} ${this.operator.getToken()}\n ${space} /\\\\\n ${space}${this.left !== null ? this.left.getOperator().getToken() : ''}\n ${space}${((this.right !== null) && (this.right.getOperator().getToken() !== undefined)) ? this.toString.call(this.right) : 'EOS'}\n `;\n }\n}\n","'use strict';\n\nimport { TokenTypes } from './Token';\nimport { Tree } from './Tree';\n\n/**\n * This class is Tree Construction (syntax tree) for MML (Music Macro Language).\n * @constructor\n */\nexport class TreeConstructor {\n /**\n * @param {Tokenizer} tokenizer This argument is the instance of `Tokenizer`.\n */\n constructor(tokenizer) {\n this.tokenizer = tokenizer; // The instance of `Tokenizer`\n this.syntaxTree = []; /** @type Array.<Tree> */\n }\n\n /**\n * This method executes tree construction (parsing) from tokens.\n * @return {Array.<Tree>} This is returned as syntax tree.\n */\n parse() {\n let token = this.tokenizer.get();\n let nextToken = this.tokenizer.get();\n\n while (true) {\n switch (token.getType()) {\n case TokenTypes.TEMPO:\n if (nextToken.getType() === TokenTypes.NUMBER) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n // /T\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TEMPO, token);\n case TokenTypes.OCTAVE:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /O\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.OCTAVE, token);\n case TokenTypes.NOTE:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /(?:[CDEFGABR][#+-]?)+\\d+\\.?/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.NOTE, token);\n case TokenTypes.REST:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /R\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.REST, token);\n case TokenTypes.NUMBER:\n // Noop\n break;\n case TokenTypes.TIE:\n if (this.syntaxTree.length > 0) {\n const tree = new Tree(token, null, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /&/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TIE, token);\n case TokenTypes.EOS:\n if (this.syntaxTree.length > 0) {\n const tree = new Tree(token, null, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n this.syntaxTree.push(tree);\n } else {\n const tree = new Tree(token, null, null);\n\n this.syntaxTree.push(tree);\n }\n\n return this.syntaxTree;\n default:\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, token);\n }\n\n token = nextToken;\n nextToken = this.tokenizer.get();\n }\n }\n\n /**\n * This method releases the memory that stack has.\n */\n free() {\n this.syntaxTree.length = 0;\n }\n}\n\n/**\n * This class is error class for MML syntax error (extends `Error`).\n * @constructor\n */\nexport class MMLSyntaxError extends Error {\n static ERRORS = {\n TEMPO : 'tempo',\n OCTAVE : 'octave',\n NOTE : 'note',\n REST : 'rest',\n TIE : 'tie',\n UNKNOWN : 'unknown'\n };\n\n /**\n * @param {string} error This argument is one of 'tempo', 'octave', 'note', 'rest', 'tie', 'unknown'.\n * @param {Token} token This argument is the instance of `Token` that error occurs in.\n */\n constructor(error, token) {\n super(error);\n\n this.token = token;\n this.error = error;\n }\n}\n","'use strict';\n\n/**\n * This class is the entity for sequence that has musical notes.\n * @constructor\n */\nexport class Sequence {\n /**\n * @param {string} note This argument is the string that corresponds to MML token.\n * @param {Array.<number>} indexes This argument is the array that contains the indexes that corresponds to the 12 equal temperament.\n * @param {Array.<number>} frequencies This argument is the array that contains the frequencies.\n * @param {number} start This argument is the start time.\n * @param {number} stop This argument is the stop time.\n * @param {number} duration This argument is the duration.\n */\n constructor(note, indexes, frequencies, start, stop, duration) {\n this.note = note;\n this.indexes = indexes;\n this.frequencies = frequencies;\n this.start = start;\n this.stop = stop;\n this.duration = duration;\n }\n\n /**\n * This method concatenates sequence in the case of tie.\n * @param {Sequence} sequence This argument is the instance of `Sequence`.\n */\n concat(sequence) {\n const s = sequence.toPlainObject();\n\n this.note += `&${s.note}`;\n this.duration += s.duration;\n\n this.stop = this.start + this.duration;\n }\n\n /**\n * This method converts the values that the instance of `Sequence` has to plain object and returns it.\n * @return {object} This is returned as the plain object that has musical notes.\n */\n toPlainObject() {\n return {\n 'note' : this.note,\n 'indexes' : this.indexes,\n 'frequencies' : this.frequencies,\n 'start' : this.start,\n 'stop' : this.stop,\n 'duration' : this.duration\n };\n }\n}\n","'use strict';\n\nimport { TokenTypes, Token } from './Token';\nimport { Tree } from './Tree';\nimport { Sequence } from './Sequence';\nimport { MMLSyntaxError } from './TreeConstructor';\n\n/**\n * This class converts syntax tree to the array that contains musical notes.\n * @constructor\n */\nexport class Sequencer {\n static FREQUENCY_RATIO = Math.pow(2, (1 / 12)); // about 1.059463\n static MIN_A = 27.5;\n static EQUAL_TEMPERAMENT = 12;\n static QUARTER_NOTE = 4;\n\n static C = 'C';\n static D = 'D';\n static E = 'E';\n static F = 'F';\n static G = 'G';\n static A = 'A';\n static B = 'B';\n static R = 'R';\n\n static SHARP = '#';\n static HALF_UP = '+';\n static HALF_DOWN = '-';\n\n static DOT = '.';\n\n /**\n * This class (static) method computes index by octave and pitch name.\n * @param {number} octave This argument is octave.\n * @param {string} pitchname This argument is pitch name.\n * @return {number} This is returned as index that is computed by octave and pitch name.\n */\n static computeIndex(octave, pitchname) {\n let index = 0;\n\n switch (pitchname) {\n case Sequencer.C:\n index = 3;\n break;\n case Sequencer.D:\n index = 5;\n break;\n case Sequencer.E:\n index = 7;\n break;\n case Sequencer.F:\n index = 8;\n break;\n case Sequencer.G:\n index = 10;\n break;\n case Sequencer.A:\n index = 12;\n break;\n case Sequencer.B:\n index = 14;\n break;\n case Sequencer.R:\n return -1;\n default:\n // eslint-disable-next-line no-console\n console.assert();\n break;\n }\n\n const computedIndex = (Sequencer.EQUAL_TEMPERAMENT * (octave - 1)) + index;\n\n return (computedIndex >= 0) ? computedIndex : -1;\n }\n\n /**\n * This class (static) method computes frequency from the index that corresponds to the 12 equal temperament.\n * @param {number} index This argument is the index that corresponds to the 12 equal temperament.\n * For example, This value is between 0 and 88 in the case of piano.\n * @return {number} This is returned as frequency.\n */\n static computeFrequency(index) {\n return (index >= 0) ? (Sequencer.MIN_A * Math.pow(Sequencer.FREQUENCY_RATIO, index)) : 0;\n }\n\n /**\n * @param {TreeConstructor} treeConstructor This argument is the instance of `TreeConstructor`.\n */\n constructor(treeConstructor) {\n this.sequences = []; /** @type {Array.<Sequence>} */\n\n this.treeConstructor = treeConstructor;\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n }\n\n /**\n * This method calculates pitch and music time from Parse Tree.\n * @return {Array.<object>|MMLSyntaxError} This is returned as array that contains sequence objects for playing the MML.\n * If error occurs, this is returned as `MMLSyntaxError`.\n */\n get() {\n const trees = this.treeConstructor.parse();\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n\n let tree = trees[0];\n\n while (tree !== null) {\n if (!(tree instanceof Tree)) {\n if (tree instanceof MMLSyntaxError) {\n return tree;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, null);\n }\n\n const operator = tree.getOperator();\n const type = operator.getType();\n\n const left = tree.getLeft();\n const right = tree.getRight();\n\n const value = left !== null ? left.getOperator().getValue() : -1;\n\n switch (type) {\n case TokenTypes.TEMPO:\n if (value <= 0) {\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TEMPO, operator.getToken());\n }\n\n this.timeOf4note = 60 / value;\n\n tree = right;\n break;\n case TokenTypes.OCTAVE:\n if (value < 0) {\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.OCTAVE, operator.getToken());\n }\n\n this.octave = value;\n\n tree = right;\n break;\n case TokenTypes.NOTE:\n case TokenTypes.REST:\n case TokenTypes.TIE :\n const r = this.push(type === TokenTypes.TIE ? right : tree);\n\n if (r instanceof MMLSyntaxError) {\n return r;\n }\n\n if (type === TokenTypes.TIE) {\n this.concat();\n\n tree = right.getRight();\n } else {\n tree = right;\n }\n\n break;\n case TokenTypes.EOS:\n tree = right;\n break;\n default:\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, null);\n }\n }\n\n // Release Memory for improving MML performance\n this.treeConstructor.free();\n\n return this.sequences;\n }\n\n /**\n * This method constructs syntax tree.\n * @param {Tree} tree This argument is the instance of `Tree` that is added to syntax tree.\n */\n push(tree) {\n const left = tree.getLeft();\n const right = tree.getRight();\n\n // Not leaf\n if ((left === null) || (right === null)) {\n return;\n }\n\n // Not leaf\n const leftToken = left.getOperator();\n const rightToken = right.getOperator();\n\n if (!(leftToken instanceof Token) && !(rightToken instanceof Token)) {\n // Traverse tree by recursive call\n this.push(left);\n this.push(right);\n return;\n }\n\n // Leaf\n const token = tree.getOperator().getToken();\n const value = leftToken.getValue();\n const digits = leftToken.getToken();\n\n const indexes = [];\n const frequencies = [];\n\n for (let i = 0, len = token.length; i < len; i++) {\n const note = token.charAt(i);\n\n let index = Sequencer.computeIndex(this.octave, note);\n\n // Sharp or Flat (Half up or Half down) ?\n switch (token.charAt(i + 1)) {\n case Sequencer.HALF_UP:\n case Sequencer.SHARP :\n index++;\n i++;\n break;\n case Sequencer.HALF_DOWN:\n index--;\n i++;\n break;\n default:\n // Normal (Natural)\n break;\n }\n\n // in the case of chord\n if (index >= indexes[0]) {\n index -= Sequencer.EQUAL_TEMPERAMENT;\n }\n\n if ((index !== -1) && (index < 0)) {\n // eslint-disable-next-line no-console\n console.assert();\n return;\n }\n\n indexes.push(index);\n }\n\n for (const index of indexes) {\n const frequency = Sequencer.computeFrequency(index);\n\n // Validation\n if (frequency < 0) {\n // eslint-disable-next-line no-console\n console.assert();\n return;\n }\n\n frequencies.push(frequency);\n }\n\n let duration = 0;\n\n switch (value) {\n case 1:\n case 2:\n case 4:\n case 8:\n case 16:\n case 32:\n case 64:\n case 128:\n case 256:\n const numberOf4note = Sequencer.QUARTER_NOTE / value;\n\n // Dotted note ?\n if (digits.includes(Sequencer.DOT)) {\n duration += 1.5 * (numberOf4note * this.timeOf4note);\n } else {\n duration += numberOf4note * this.timeOf4note;\n }\n\n break;\n case 6:\n // Triplet of half note\n duration += (2 * this.timeOf4note) / 3;\n break;\n case 12:\n // Triplet of quarter note\n duration += this.timeOf4note / 3;\n break;\n case 18:\n // Nonuplet of half note\n duration += (2 * this.timeOf4note) / 9;\n break;\n case 24:\n // Triplet of 8th note\n duration += (0.5 * this.timeOf4note) / 3;\n break;\n case 36:\n // Nonuplet of quarter note\n duration += this.timeOf4note / 9;\n break;\n case 48:\n // Triplet of 16th note\n duration += (0.25 * this.timeOf4note) / 3;\n break;\n case 72:\n // Nonuplet of 8th note\n duration += (0.5 * this.timeOf4note) / 9;\n break;\n case 96:\n // Triplet of 32th note\n duration += (0.125 * this.timeOf4note) / 3;\n break;\n case 144:\n // Nonuplet of 16th note\n duration += (0.25 * this.timeOf4note) / 9;\n break;\n case 192:\n // Triplet of 64th note\n duration += (0.0625 * this.timeOf4note) / 3;\n break;\n default:\n // eslint-disable-next-line no-console\n console.assert();\n break;\n }\n\n this.sequences.push(new Sequence(\n `${token}${digits}`,\n indexes,\n frequencies,\n this.currentTime,\n (this.currentTime + duration),\n duration\n ));\n\n this.currentTime += duration;\n }\n\n /**\n * This method concats previous note and previous duration and current note and current duration in the case of tie.\n */\n concat() {\n const current = this.sequences.pop();\n const previous = this.sequences.pop();\n\n previous.concat(current);\n\n this.sequences.push(previous);\n }\n}\n","'use strict';\n\nimport { Tokenizer } from './Tokenizer';\nimport { TreeConstructor, MMLSyntaxError } from './TreeConstructor';\nimport { Sequencer } from './Sequencer';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { NoiseModule } from '../NoiseModule';\n\n/**\n * This class parses, starts and stops MML as each MML part.\n * @constructor\n */\nexport class Part {\n /**\n * @param {OscillatorModule|OneshotModule|NoiseModule} source This argument is in order to select sound source.\n * @param {string} mml This argument is MML string.\n * @param {number} offset This argument is in order to correct the index of one-shot audio.\n * @param {object.<string, function>} callbacks This argument is callback functions.\n * @param {number} offset This argument is in order to correct the index of one-shot audio.\n */\n constructor(source, mml, callbacks, offset) {\n this.source = null; /** @type {OscillatorModule|OneshotModule|NoiseModule} */\n this.mml = '';\n this.previous = null; /** @type {Sequence} */\n this.timerid = null; /** @type {number} */\n this.currentIndex = 0; /** @type {number} */\n this.currentPosition = 0; /** @type {number} */\n this.offset = 0;\n\n if ((source instanceof OscillatorModule) || (source instanceof OneshotModule) || (source instanceof NoiseModule)) {\n this.source = source;\n }\n\n if (typeof mml === 'string') {\n this.mml = mml;\n }\n\n this.callbacks = {\n 'start' : () => {},\n 'stop' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n\n if (Object.prototype.toString.call(callbacks) === '[object Object]') {\n Object.keys(callbacks).forEach(key => {\n const k = key.toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(callbacks[k]) === '[object Function]') {\n this.callbacks[k] = callbacks[k];\n }\n }\n });\n }\n\n const o = parseInt(offset, 10);\n\n if (!isNaN(o) && (o >= 0)) {\n this.offset = o;\n }\n\n const tokenizer = new Tokenizer(mml);\n const treeConstructor = new TreeConstructor(tokenizer);\n const sequencer = new Sequencer(treeConstructor);\n\n this.sequences = sequencer.get();\n\n if ((this.sequences instanceof MMLSyntaxError) && this.callbacks.error) {\n this.callbacks.error(this.sequences);\n }\n }\n\n /**\n * This method starts MML. Moreover, this method schedules next sequence.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Effector>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n */\n start(highlight, connects) {\n if (!this.sequences[this.currentIndex]) {\n this.stop();\n this.callbacks.ended();\n\n return;\n }\n\n const sequence = this.sequences[this.currentIndex++].toPlainObject();\n\n if (highlight) {\n const prev = this.mml.slice(0, this.currentPosition);\n const current = this.mml.slice(this.currentPosition).replace(sequence.note, `<span class=\"x-highlight\">${sequence.note}</span>`);\n\n this.mml = `${prev}${current}`;\n\n this.currentPosition += this.mml.slice(this.currentPosition).indexOf('</span>') + '</span>'.length;\n } else {\n const prev = this.mml.slice(0, this.currentPosition);\n const current = sequence.note;\n\n this.mml = `${prev}${current}`;\n\n this.currentPosition += current.length;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.ready(0, sequence.duration).start(sequence.frequencies);\n this.callbacks.start(sequence);\n } else if (this.source instanceof OneshotModule) {\n for (let i = 0, len = sequence.indexes.length; i < len; i++) {\n if (sequence.indexes[i] !== -1) {\n this.source.ready(0, sequence.duration).start(sequence.indexes[i] + this.offset);\n }\n }\n\n this.callbacks.start(sequence, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.start(connects);\n this.callbacks.start(sequence);\n }\n\n this.timerid = window.setTimeout(() => {\n if (this.source instanceof OscillatorModule) {\n this.callbacks.stop(sequence);\n } else if (this.source instanceof OneshotModule) {\n this.callbacks.stop(sequence, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n this.callbacks.stop(sequence);\n }\n\n // for stopping MML\n this.previous = sequence;\n\n // Start next sequence\n this.start(highlight, connects);\n }, (sequence.duration * 1000));\n }\n\n /**\n * This method stops MML.\n */\n stop() {\n if (this.previous === null) {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.stop();\n this.callbacks.stop(this.previous);\n } else if (this.source instanceof OneshotModule) {\n for (const index of this.previous.indexes) {\n if (index !== -1) {\n this.source.stop((index + this.offset));\n }\n }\n\n this.callbacks.stop(this.previous, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n this.callbacks.stop(this.previous);\n }\n\n window.clearTimeout(this.timerid);\n this.timerid = null;\n }\n\n /**\n * This method is the getter for MML string.\n */\n getMML() {\n return this.mml;\n }\n\n /**\n * This method is the getter for sequence.\n */\n getSequence() {\n return this.sequences;\n }\n\n /**\n * This method determines whether the sequence exists.\n * @return {boolean} If the sequence exists, this value is `true`. Otherwise, this value is `false`.\n */\n hasSequence() {\n return this.sequences.length > 0;\n }\n\n /**\n * This method determines whether the MMLs are paused.\n * @return {boolean} If the MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n paused() {\n return this.timerid === null;\n }\n\n /**\n * This method is the getter for current sequence index.\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * This method is the setter for current sequence index.\n * @param {number} index This argument is the number that is new sequence index.\n */\n setCurrentIndex(index) {\n const i = parseInt(index, 10);\n\n if (i >= 0 && i < this.sequences.length) {\n this.currentIndex = i;\n }\n }\n}\n","'use strict';\n\nimport { Part } from './Part';\n\n/**\n * This class manages the instances of `Part` for playing the MML (Music Macro Language).\n * @constructor\n */\nexport class MML {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.parts = []; /** @type {Array.<Part>} */\n\n this.callbacks = {\n 'start' : () => {},\n 'stop' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n }\n\n /**\n * This method sets callback functions.\n * @param {string|object} key This argument is property name.\n * This argument is pair of property and value in the case of associative array.\n * @param {function} value This argument is callback function.\n * @return {MML} This is returned for method chain.\n */\n setup(key, value) {\n if ((arguments.length > 0) && (Object.prototype.toString.call(arguments[0]) === '[object Object]')) {\n // Associative array\n for (const k in arguments[0]) {\n this.setup(k, arguments[0][k]);\n }\n } else if (arguments.length > 1) {\n const k = String(key).toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(value) === '[object Function]') {\n this.callbacks[k] = value;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method parses MML string.\n * @param {OscillatorModule|OneshotModule|NoiseModule} source This argument is in order to select sound source.\n * @param {Array.<string>} mmls This argument is MML strings.\n * @param {number} offset This argument is in order to adjust the index of one-shot audio.\n * @return {Array.<Array.<Sequence>>} This is returned as array that contains `Sequence` for playing the MML.\n */\n ready(source, mmls, offset) {\n if (!Array.isArray(mmls) && (typeof mmls === 'string')) {\n mmls = [mmls];\n }\n\n if (!Array.isArray(mmls)) {\n return this;\n }\n\n this.stop();\n this.clear();\n\n this.mmls = mmls;\n\n for (const mml of mmls) {\n this.parts.push(new Part(source, mml, this.callbacks, offset));\n }\n\n return this;\n }\n\n /**\n * This method starts the designated MML part. Moreover, this method schedules next sequence.\n * @param {number} part This argument is the part of MML.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Connectable>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n * @return {MML} This is returned for method chain.\n */\n start(part, highlight, connects) {\n const p = parseInt(part, 10);\n\n if ((p >= 0) && (p < this.parts.length)) {\n const part = this.parts[p];\n\n part.start(highlight, connects);\n }\n\n return this;\n }\n\n /**\n * This method stops the all of MML parts.\n * @return {MML} This is returned for method chain.\n */\n stop() {\n for (const part of this.parts) {\n part.stop();\n }\n\n return this;\n }\n\n /**\n * This method gets the array that contains string or object for playing the MML.\n * @param {number} index This argument is required in the case of designating MML part or sequence object.\n * @param {boolean} asMML This argument is 'mml' in the case of getting string or array as MML.\n * @return {Array.<string>|string|Array.<Array.<object>>|Array.<object>}\n */\n get(index, asMML) {\n const i = parseInt(index, 10);\n\n const mmls = [];\n const sequences = [];\n\n for (const part of this.parts) {\n mmls.push(part.getMML());\n sequences.push(part.getSequence());\n }\n\n if (asMML) {\n return ((i >= 0) && (i < this.parts.length)) ? this.parts[i].getMML() : mmls;\n }\n\n return ((i >= 0) && (i < this.parts.length)) ? this.parts[i].getSequence() : sequences;\n }\n\n /**\n * This method starts or stops MML according to state.\n * @param {number} part This argument is the part of MML.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Connectable>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n * @return {MML} This is returned for method chain.\n */\n toggle(part, highlight, connects) {\n if (this.isPaused()) {\n this.start(part, highlight, connects);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method determines whether the sequences exist.\n * @return {boolean} If the sequences exist, this value is `true`. Otherwise, this value is `false`.\n */\n isSequences() {\n return (this.parts.length > 0) && this.parts.every(part => part.hasSequence());\n }\n\n /**\n * This method determines whether the MMLs are paused.\n * @return {boolean} If the MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n isPaused() {\n return (this.parts.length === 0) || this.parts.every(part => part.paused());\n }\n\n /**\n * This method gets or sets current sequence index.\n * @param {number} part This argument is the part of MML.\n * @param {number} index If this argument is number, this is new sequence index.\n * If this argument is omitted, this method is getter for current sequence index.\n * @return {number|MML} This is returned as current sequence index. Otherwise, this is returned for method chain.\n */\n currentIndex(part, index) {\n const p = parseInt(part, 10);\n\n if ((p < 0) || (p >= this.parts.length)) {\n return this;\n }\n\n if (index === undefined) {\n return this.parts[p].getCurrentIndex();\n }\n\n this.parts[p].setCurrentIndex(index);\n\n return this;\n }\n\n /**\n * This method converts MML to ABC Notation.\n * @param {string} mml This argument is MML string.\n * @param {number} X This argument is file number in ABC Notation.\n * @param {string} T This argument is title in ABC Notation.\n * @param {string} M This argument is beat in ABC Notation.\n * @param {string} L This argument is note duration in ABC Notation.\n * @param {string} K This argument is tone in ABC Notation.\n * @return {string} This is returned as ABC Notation.\n */\n toABC(mml, X, T, M, L, K) {\n let abc = '';\n\n abc += `X:${X ? X : 1}\\n`;\n abc += `T:${T ? T : ''}\\n`;\n abc += `M:${M ? M : '4/4'}\\n`;\n abc += `L:${L ? L : '1/256'}\\n`;\n abc += `K:${K ? K : ''}\\n`;\n\n const notes = mml.match(/\\s*(?:T\\d+)\\s*|\\s*(?:O\\d+)\\s*|\\s*(?:(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)(?:&(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)*\\s*/gi);\n\n if (notes === null) {\n return abc;\n }\n\n let octave = null;\n let totalDuration = 0;\n\n while (notes.length > 0) {\n const note = notes.shift().trim();\n\n if (/T\\d+/i.test(note)) {\n const Q = parseInt(note.slice(1), 10);\n\n if (Q <= 0) {\n return abc;\n }\n\n abc += `Q:1/4=${Q}\\n`;\n } else if (/O\\d+/i.test(note)) {\n octave = parseInt(note.slice(1), 10);\n\n if (octave < 0) {\n return abc;\n }\n } else if (/(?:(?:[CDEFGABR][#+-]?)+)(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)(?:&(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)*/i.test(note)) {\n if (octave === null) {\n return abc;\n }\n\n let splittedNotes = null;\n\n if (note.indexOf('&') === -1) {\n splittedNotes = [note];\n } else {\n splittedNotes = note.split('&');\n }\n\n let chord = '';\n\n while (splittedNotes.length > 0) {\n const splittedNote = splittedNotes.shift();\n\n const duration = parseInt(splittedNote.replace(/^.+?(\\d+)\\.*$/, '$1'), 10);\n\n let n = '';\n let d = 0;\n\n switch (duration) {\n case 1:\n n = splittedNote.replace('1', '256');\n break;\n case 2:\n n = splittedNote.replace('2', '128');\n break;\n case 4:\n n = splittedNote.replace('4', '64');\n break;\n case 8:\n n = splittedNote.replace('8', '32');\n break;\n case 16:\n n = splittedNote.replace('16', '16');\n break;\n case 32:\n n = splittedNote.replace('32', '8');\n break;\n case 64:\n n = splittedNote.replace('64', '4');\n break;\n case 128:\n n = splittedNote.replace('128', '2');\n break;\n case 256:\n n = splittedNote.replace('256', '1');\n break;\n // Tuplet\n case 6:\n n = `(3${splittedNote.replace('6', '128')}`;\n d = 128 / 3;\n break;\n case 12:\n n = `(3${splittedNote.replace('12', '64')}`;\n d = 64 / 3;\n break;\n case 18:\n n = `(9${splittedNote.replace('18', '128')}`;\n d = 128 / 9;\n break;\n case 24:\n n = `(3${splittedNote.replace('24', '32')}`;\n d = 32 / 3;\n break;\n case 36:\n n = `(9${splittedNote.replace('36', '64')}`;\n d = 64 / 9;\n break;\n case 48:\n n = `(3${splittedNote.replace('48', '16')}`;\n d = 16 / 3;\n break;\n case 72:\n n = `(9${splittedNote.replace('72', '32')}`;\n d = 32 / 9;\n break;\n case 96:\n n = `(3${splittedNote.replace('96', '8')}`;\n d = 8 / 3;\n break;\n case 144:\n n = `(9${splittedNote.replace('144', '16')}`;\n d = 16 / 9;\n break;\n case 192:\n n = `(3${splittedNote.replace('192', '4')}`;\n d = 4 / 3;\n break;\n default:\n return abc;\n }\n\n if (n.indexOf('.') !== -1) {\n n = n.replace(/^(.+?)\\d+\\.+$/, `$1${1.5 * parseInt(n.replace(/^.+?(\\d+)\\.+$/, '$1'), 10)}`);\n }\n\n if (n.indexOf('(') === -1) {\n totalDuration += parseInt(n.replace(/^.+?(\\d+)\\.*$/i, '$1'), 10);\n } else {\n totalDuration += d;\n }\n\n if (totalDuration >= 256) {\n n += ' | ';\n totalDuration = 0;\n }\n\n if (/R/i.test(n)) {\n abc += `${n} `;\n continue;\n }\n\n let o = '';\n\n switch (octave) {\n case 0:\n o = ',,,,';\n break;\n case 1:\n o = ',,,';\n break;\n case 2:\n o = ',,';\n break;\n case 3:\n o = ',';\n break;\n case 5:\n o = '\\'';\n break;\n case 6:\n o = '\\'\\'';\n break;\n case 7:\n o = '\\'\\'\\'';\n break;\n case 4 :\n default:\n break;\n }\n\n const matches = n.match(/^(\\(\\d+)?((?:[CDEFGAB][#+-]?)+)(.*)$/i);\n\n if (matches === null) {\n return abc;\n }\n\n const tuplet = matches[1] ? matches[1] : '';\n const chordLength = matches[2].length;\n const restNote = matches[3] ? matches[3] : '';\n\n let start = 0;\n\n if (tuplet.length > 0) {\n n = n.replace(/^(?:\\(\\d+)?((?:[CDEFGAB][#+-]?)+)(.*)$/i, '$1$2');\n }\n\n if (chordLength === 1) {\n chord += `${tuplet}${n.slice(0, 1)}${o}${restNote}`;\n } else if ((chordLength === 2) && /[#+-]/.test(n.charAt(1))) {\n chord += `${tuplet}${n.slice(1, 2)}${n.slice(0, 1)}${o}${restNote}`;\n } else {\n while (start < chordLength) {\n if (start === 0) {\n chord += `${tuplet}[`;\n }\n\n if (/[#+-]/.test(n.charAt(start + 1))) {\n chord += `${n.slice((start + 1), (start + 2))}${n.slice(start, (start + 1))}${o}`;\n start += 2;\n } else {\n chord += `${n.slice(start, (start + 1))}${o}`;\n start++;\n }\n\n if (start === chordLength) {\n chord += `]${restNote}`;\n }\n }\n }\n\n if (splittedNotes.length > 0) {\n chord += '&';\n } else {\n abc += `${chord} `;\n }\n }\n }\n }\n\n return abc.replace(/R/gi, 'z')\n .replace(/[#+]/g, '^')\n .replace(/-/g, '_')\n .replace(/&/g, '-')\n .replace(/\\s{2}/g, ' ')\n .trim();\n }\n\n /**\n * This method clears the instances of `Part`.\n * @return {MML} This is returned for method chain.\n */\n clear() {\n for (const part of this.parts) {\n part.stop();\n }\n\n // Garbage Collection\n this.parts.length = 0;\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[MML]';\n }\n}\n","'use strict';\n\n/**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\nexport function FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n}\n\n/**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\nexport function IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n}\n\n/**\n * This class (static) method gets audio data as `ArrayBuffer` by Ajax.\n * @param {string} url This argument is URL for audio resource.\n * @param {type} string This argument is response type that is one of 'text', 'arraybuffer', 'blob', 'document', 'json'. The default value is 'arraybuffer'.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n */\nexport function ajax(url, type, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('url' in properties) {\n url = properties.url;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n // for errorCallback\n const ERROR_AJAX = 'error';\n const ERROR_AJAX_TIMEOUT = 'timeout';\n\n const xhr = new XMLHttpRequest();\n\n const t = parseInt(timeout, 10);\n\n xhr.timeout = (t > 0) ? t : 60000;\n\n xhr.ontimeout = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event, ERROR_AJAX_TIMEOUT);\n }\n };\n\n xhr.onprogress = event => {\n if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event, ERROR_AJAX);\n }\n };\n\n xhr.onload = event => {\n if ((xhr.status === 200) && (Object.prototype.toString.call(successCallback) === '[object Function]')) {\n successCallback(event, xhr.response);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = /text|arraybuffer|blob|document|json/.test(String(type).toLowerCase()) ? String(type).toLowerCase() : 'arraybuffer';\n xhr.send(null);\n}\n\n/**\n * This class (static) method calculates minutes and seconds from the designated time in seconds.\n * @param {number} time This argument is the time in seconds.\n * @return {object} This is returned as associative array that contains `minutes`, `seconds` and `milliseconds` keys.\n */\nexport function convertTime(time) {\n const t = parseFloat(time);\n\n if (t >= 0) {\n const m = Math.floor(t / 60);\n const s = Math.floor(t % 60);\n const ms = t - Math.floor(t);\n\n return {\n 'minutes' : m,\n 'seconds' : s,\n 'milliseconds' : ms\n };\n }\n}\n\n/**\n * This class (static) method creates the instance of `AudioBuffer` from `ArrayBuffer`.\n * @param {AudioContext} context This argument is the instance of `AudioContext` for `decodeAudioData` method.\n * @param {ArrayBuffer} arrayBuffer This argument is converted to the instance of `AudioBuffer`.\n * @param {function} successCallback This argument is invoked when `decodeAudioData` method is successful.\n The 1st argument in this callback function is the instance of `AudioBuffer`.\n * @param {function} errorCallback This argument is invoked when `decodeAudioData` method failed.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function decode(context, arrayBuffer, successCallback, errorCallback) {\n if (!(context instanceof AudioContext)) {\n return;\n }\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n if (Object.prototype.toString.call(successCallback) !== '[object Function]') {\n successCallback = () => {};\n }\n\n if (Object.prototype.toString.call(errorCallback) !== '[object Function]') {\n errorCallback = () => {};\n }\n\n return context.decodeAudioData(arrayBuffer, successCallback, errorCallback);\n}\n\n/**\n * This class (static) method shows `Element` in original size from full screen.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function exitFullscreen() {\n if (document.exitFullscreen) {\n return document.exitFullscreen();\n }\n\n if (document.webkitCancelFullScreen) {\n return document.webkitCancelFullScreen();\n }\n\n if (document.mozCancelFullScreen) {\n return document.mozCancelFullScreen();\n }\n\n if (document.msExitFullscreen) {\n return document.msExitFullscreen();\n }\n\n if (document.cancelFullScreen) {\n return document.cancelFullScreen();\n }\n\n return Promise.reject('Cannot exit from full screen.');\n}\n\n/**\n * This class (static) method gets the instance of `File` (extends `Blob`).\n * @param {Event} event This argument is the instance of Event by Drag & Drop or `<input type=\"file\">`.\n * @param {string} type This argument is one of 'ArrayBuffer', 'DataURL', 'ObjectURL', 'Text', 'JSON'.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when reading file failed.\n * @param {function} progressCallback This argument is invoked as `onprogress` event handler in the instance of `FileReader`.\n * @return {File|ObjectURL} This is returned as the instance of `File` (extends `Blob`) or Object URL.\n */\nexport function file(event, type, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('event' in properties) {\n event = properties.event;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!(event instanceof Event)) {\n return;\n }\n\n // for the instance of `File` (extends `Blob`)\n let file = null;\n\n if (event.type === 'drop') {\n // Drag & Drop\n event.stopPropagation();\n event.preventDefault();\n\n file = /* ('items' in event.dataTransfer) ? event.dataTransfer.items[0].getAsFile() : */event.dataTransfer.files[0];\n } else if ((event.type === 'change') && ('files' in event.target)) {\n // `<input type=\"file\">`\n file = event.target.files[0];\n } else {\n return;\n }\n\n if (!(file instanceof File)) {\n throw new Error('Please upload file.');\n } else if ((/text/i.test(type)) && !file.type.includes('text')) {\n throw new Error('Please upload text file.');\n } else if (/json/i.test(type) && !file.type.includes('application/json')) {\n throw new Error('Please upload JSON file.');\n } else if ((/arraybuffer|dataurl/i.test(type)) && !/audio|video/.test(file.type)) {\n throw new Error('Please upload audio or video file.');\n } else {\n if (/objecturl/i.test(type)) {\n return window.URL.createObjectURL(file);\n }\n\n read({\n 'file' : file,\n 'type' : type,\n 'success' : successCallback,\n 'error' : errorCallback,\n 'progress' : progressCallback\n });\n\n return file;\n }\n}\n\n/**\n * This class (static) method reads file of audio or text.\n * @param {Blob} file This argument is the instance of `Blob`. This is entity of file.\n * @param {string} type This argument is one of 'ArrayBuffer', 'DataURL', 'Text'.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when reading file failed.\n * @param {function} progressCallback This argument is invoked as `onprogress` event handler in the instance of `FileReader`.\n */\nexport function read(file, type, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('file' in properties) {\n file = properties.file;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!(file instanceof Blob)) {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(null, 'FILE_IS_NOT_BLOB');\n }\n\n return;\n }\n\n const reader = new FileReader();\n\n reader.onprogress = event => {\n if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n reader.onerror = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n let error = '';\n\n switch (reader.error.code) {\n case reader.error.NOT_FOUND_ERR:\n error = 'NOT_FOUND_ERR';\n break;\n case reader.error.SECURITY_ERR:\n error = 'SECURITY_ERR';\n break;\n case reader.error.ABORT_ERR:\n error = 'ABORT_ERR';\n break;\n case reader.error.NOT_READABLE_ERR:\n error = 'NOT_READABLE_ERR';\n break;\n case reader.error.ENCODING_ERR:\n error = 'ENCODING_ERR';\n break;\n default:\n error = 'ERR';\n break;\n }\n\n errorCallback(event, error);\n }\n };\n\n reader.onload = event => {\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n let result = reader.result;\n\n // Escape `<script>` in the case of text\n if ((typeof result === 'string') && !result.includes('data:') && !result.indexOf('blob:')) {\n result = result.replace(/<(\\/?script.*?)>/gi, '&lt;$1&gt;');\n }\n\n successCallback(event, result);\n }\n };\n\n if (/arraybuffer/i.test(type)) {\n reader.readAsArrayBuffer(file);\n } else if (/dataurl/i.test(type)) {\n reader.readAsDataURL(file);\n } else if (/text|json/i.test(type)) {\n reader.readAsText(file, 'UTF-8');\n }\n}\n\n/**\n * This class (static) method shows the designated `Element` in full screen.\n * @param {Element} element This argument is the instance of `Element` that is the target of full screen.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function requestFullscreen(element) {\n if (!(element instanceof Element)) {\n return Promise.reject('Invalid argument.');\n }\n\n if (element.requestFullscreen) {\n return element.requestFullscreen();\n }\n\n if (element.webkitRequestFullscreen) {\n return element.webkitRequestFullscreen();\n }\n\n if (element.mozRequestFullScreen) {\n return element.mozRequestFullScreen();\n }\n\n if (element.msRequestFullscreen) {\n return element.msRequestFullscreen();\n }\n\n return Promise.reject('Cannot change to full screen.');\n}\n\n/**\n * This class (static) method calculates frequency from the index that corresponds to the 12 equal temperament.\n * @param {Array.<number>} indexes This argument is array of index that corresponds to the 12 equal temperament.\n * For example, This value is between 0 and 88 in the case of piano.\n * @return {Array.<number>} This is returned as array that contains frequencies.\n */\nexport function toFrequencies(indexes) {\n // The 12 equal temperament\n //\n // Min -> 27.5 Hz (A), Max -> 4186 Hz (C)\n //\n // A * 1.059463 -> A# (half up)\n\n const FREQUENCY_RATIO = Math.pow(2, (1 / 12)); // about 1.059463\n const MIN_A = 27.5;\n\n if (!Array.isArray(indexes)) {\n indexes = [indexes];\n }\n\n const frequencies = new Array(indexes.length);\n\n for (let i = 0, len = indexes.length; i < len; i++) {\n const index = parseInt(indexes[i], 10);\n\n frequencies[i] = (index >= 0) ? (MIN_A * Math.pow(FREQUENCY_RATIO, index)) : 0;\n }\n\n return frequencies;\n}\n\n/**\n * This class (static) method creates text file.\n * @param {string} text This argument is string.\n * @return {string} This is returned as text file.\n */\nexport function toTextFile(text) {\n /**\n * This function converts string to ASCII string.\n * @param {string} string This argument is string.\n * @return {string} This is returned as string that is converted to ASCII string.\n */\n const toAscii = string => {\n let converted = '';\n\n for (let i = 0, len = string.length; i < len; i++) {\n const charCode = string.charCodeAt(i);\n\n if (charCode > 0xFF) {\n converted += `&#${charCode};`;\n } else {\n converted += string.charAt(i);\n }\n }\n\n return converted;\n };\n\n const base64 = window.btoa(toAscii(String(text)));\n const dataURL = `data:text/plain;base64,${base64}`;\n\n return dataURL;\n}\n","'use strict';\n\nimport { SoundModule } from './SoundModule';\nimport { OscillatorModule } from './OscillatorModule';\nimport { OneshotModule } from './OneshotModule';\nimport { NoiseModule } from './NoiseModule';\nimport { AudioModule } from './AudioModule';\nimport { MediaModule } from './MediaModule';\nimport { StreamModule } from './StreamModule';\nimport { MixerModule } from './MixerModule';\nimport { ProcessorModule } from './ProcessorModule';\nimport { MIDI } from './MIDI';\nimport { MML } from './MML';\nimport { Analyser } from './SoundModule/Analyser';\nimport { Recorder } from './SoundModule/Recorder';\nimport { Session } from './SoundModule/Session';\nimport { Effector } from './SoundModule/Effectors/Effector';\nimport { Autopanner } from './SoundModule/Effectors/Autopanner';\nimport { Chorus } from './SoundModule/Effectors/Chorus';\nimport { Compressor } from './SoundModule/Effectors/Compressor';\nimport { Delay } from './SoundModule/Effectors/Delay';\nimport { Distortion } from './SoundModule/Effectors/Distortion';\nimport { Equalizer } from './SoundModule/Effectors/Equalizer';\nimport { Filter } from './SoundModule/Effectors/Filter';\nimport { Flanger } from './SoundModule/Effectors/Flanger';\nimport { Listener } from './SoundModule/Effectors/Listener';\nimport { Panner } from './SoundModule/Effectors/Panner';\nimport { Phaser } from './SoundModule/Effectors/Phaser';\nimport { PitchShifter } from './SoundModule/Effectors/PitchShifter';\nimport { Reverb } from './SoundModule/Effectors/Reverb';\nimport { Ringmodulator } from './SoundModule/Effectors/Ringmodulator';\nimport { Stereo } from './SoundModule/Effectors/Stereo';\nimport { Tremolo } from './SoundModule/Effectors/Tremolo';\nimport { Wah } from './SoundModule/Effectors/Wah';\nimport {\n FFT,\n IFFT,\n ajax,\n convertTime,\n decode,\n exitFullscreen,\n file,\n requestFullscreen,\n read,\n toFrequencies,\n toTextFile\n} from './XSound';\n\nconst global = (typeof window !== 'undefined') ? window : {};\n\n// for legacy browsers\nglobal.AudioContext = global.AudioContext || global.webkitAudioContext;\nglobal.MediaSource = global.MediaSource || global.WebkitMediaSource;\nglobal.URL = global.URL || global.webkitURL || global.mozURL;\n\nglobal.requestAnimationFrame = global.requestAnimationFrame ||\n global.webkitRequestAnimationFrame ||\n global.mozRequestAnimationFrame ||\n (callback => global.setTimeout(callback, (1000 / 60)));\n\nglobal.cancelAnimationFrame = global.cancelAnimationFrame ||\n global.webkitCancelAnimationFrame ||\n global.mozCancelAnimationFrame ||\n global.clearTimeout;\n\nlet XSound;\n\nconst IS_XSOUND = Boolean(global.AudioContext);\n\nif (IS_XSOUND) {\n const audiocontext = new AudioContext();\n\n // for legacy browsers\n audiocontext.createScriptProcessor = audiocontext.createScriptProcessor || audiocontext.createJavaScriptNode;\n audiocontext.createGain = audiocontext.createGain || audiocontext.createGainNode;\n audiocontext.createDelay = audiocontext.createDelay || audiocontext.createDelayNode;\n audiocontext.createPeriodicWave = audiocontext.createPeriodicWave || audiocontext.createWaveTable;\n\n const sources = {\n 'oscillator' : new OscillatorModule(audiocontext),\n 'oneshot' : new OneshotModule(audiocontext),\n 'noise' : new NoiseModule(audiocontext),\n 'audio' : new AudioModule(audiocontext),\n 'media' : new MediaModule(audiocontext),\n 'stream' : new StreamModule(audiocontext),\n 'mixer' : new MixerModule(audiocontext),\n 'processor' : new ProcessorModule(audiocontext),\n 'midi' : new MIDI(audiocontext),\n 'mml' : new MML(audiocontext)\n };\n\n /**\n * This function is global object for getting the instance of `OscillatorModule` or `OneshotModule` or `NoiseModule` or `AudioModule` or `MediaModule` or `StreamModule` or `MixerModule` or `ProcessorModule` or `MIDI` or `MML` or `Oscillator`.\n * @param {string} source This argument is one of 'oscillator', 'oneshot', 'noise', 'audio', 'media', 'stream', 'mixer', 'processor', 'midi', 'mml'.\n * @param {number} index This argument is in order to select one of some oscillators.\n * @return {OscillatorModule|OneshotModule|NoiseModule|AudioModule|MediaModule|StreamModule|MixerModule|ProcessorModule|MIDI|MML|Oscillator}\n */\n XSound = (source, index) => {\n const s = String(source).replace(/-/g, '').toLowerCase();\n\n switch (s) {\n case 'oscillator':\n if (index === undefined) {\n return sources.oscillator;\n }\n\n const i = parseInt(index, 10);\n\n if ((i >= 0) && (i < sources.oscillator.length())) {\n return sources.oscillator.get(i);\n }\n\n return null;\n case 'oneshot' :\n case 'noise' :\n case 'audio' :\n case 'media' :\n case 'stream' :\n case 'mixer' :\n case 'processor':\n case 'midi' :\n case 'mml' :\n return sources[s];\n default :\n return null;\n }\n };\n\n /**\n * Class (Static) properties\n */\n XSound.IS_XSOUND = IS_XSOUND;\n XSound.SAMPLE_RATE = audiocontext.sampleRate;\n XSound.NUMBER_OF_INPUTS = SoundModule.NUMBER_OF_INPUTS;\n XSound.NUMBER_OF_OUTPUTS = SoundModule.NUMBER_OF_OUTPUTS;\n XSound.FFT = FFT;\n XSound.IFFT = IFFT;\n XSound.ajax = ajax;\n XSound.convertTime = convertTime;\n XSound.decode = decode;\n XSound.exitFullscreen = exitFullscreen;\n XSound.file = file;\n XSound.requestFullscreen = requestFullscreen;\n XSound.read = read;\n XSound.toFrequencies = toFrequencies;\n XSound.toTextFile = toTextFile;\n\n XSound.Analyser = Analyser;\n XSound.Recorder = Recorder;\n XSound.Session = Session;\n\n XSound.Effector = Effector;\n XSound.Autopanner = Autopanner;\n XSound.Chorus = Chorus;\n XSound.Compressor = Compressor;\n XSound.Delay = Delay;\n XSound.Distortion = Distortion;\n XSound.Equalizer = Equalizer;\n XSound.Filter = Filter;\n XSound.Flanger = Flanger;\n XSound.Listener = Listener;\n XSound.Panner = Panner;\n XSound.Phaser = Phaser;\n XSound.PitchShifter = PitchShifter;\n XSound.Reverb = Reverb;\n XSound.Ringmodulator = Ringmodulator;\n XSound.Stereo = Stereo;\n XSound.Tremolo = Tremolo;\n XSound.Wah = Wah;\n\n /**\n * This class (static) method changes state ('running') of `AudioContext`.\n * The initial state is 'suspended' by Autoplay Policy Change.\n * Therefore, this method must be invoked by user gestures.\n * @return {Promise} This is returned as `Promise`.\n */\n XSound.setup = () => {\n if (audiocontext.state !== 'running') {\n return audiocontext.resume();\n }\n\n return Promise.reject();\n };\n\n /**\n * This class (static) method returns function as closure that is getter of cloned module.\n * @return {function} This is returned as closure that is getter of cloned module.\n */\n XSound.clone = () => {\n const clones = {\n 'oscillator' : new OscillatorModule(audiocontext),\n 'oneshot' : new OneshotModule(audiocontext),\n 'noise' : new NoiseModule(audiocontext),\n 'audio' : new AudioModule(audiocontext),\n 'media' : new MediaModule(audiocontext),\n 'stream' : new StreamModule(audiocontext),\n 'mixer' : new MixerModule(audiocontext),\n 'processor' : new ProcessorModule(audiocontext),\n 'midi' : new MIDI(audiocontext),\n 'mml' : new MML(audiocontext)\n };\n\n const C = (source, index) => {\n const s = String(source).replace(/-/g, '').toLowerCase();\n\n switch (s) {\n case 'oscillator':\n if (index === undefined) {\n return clones.oscillator;\n }\n\n const i = parseInt(index, 10);\n\n if ((i >= 0) && (i < clones.oscillator.length())) {\n return clones.oscillator.get(i);\n }\n\n return null;\n case 'oneshot' :\n case 'noise' :\n case 'audio' :\n case 'media' :\n case 'stream' :\n case 'mixer' :\n case 'processor':\n case 'midi' :\n case 'mml' :\n return clones[s];\n default :\n return null;\n }\n };\n\n C.free = sourceList => {\n if (!Array.isArray(sourceList)) {\n sourceList = [sourceList];\n }\n\n for (const source of sourceList) {\n // Already deleted ?\n if (source === null) {\n continue;\n }\n\n for (const key in clones) {\n if (source === clones[key]) {\n clones[key] = null;\n }\n }\n }\n };\n\n // Closure\n return C;\n };\n\n /**\n * This class (static) method releases memory of unnecessary instances.\n * @param {Array.<SoundModule|MIDI|MML>} sourceList This argument is the array that contains the instances of `SoundModule` or `MIDI` or `MML`.\n */\n XSound.free = sourceList => {\n if (!Array.isArray(sourceList)) {\n sourceList = [sourceList];\n }\n\n for (const source of sourceList) {\n // Already deleted ?\n if (source === null) {\n continue;\n }\n\n for (const key in sources) {\n if (source === sources[key]) {\n sources[key] = null;\n }\n }\n }\n };\n\n /**\n * This class (static) method removes one of the global objects or both of the global objects.\n * @param {boolean} deep This argument is in order to select whether removing both of global objects.\n * If this value is `true`, both of global objects are removed.\n * @return {XSound}\n */\n XSound.noConflict = deep => {\n if (window.X === XSound) {\n window.X = undefined;\n }\n\n // both of global objects are removed ?\n if (deep && (window.XSound === XSound)) {\n window.XSound = undefined;\n }\n\n return XSound;\n };\n\n /**\n * This class (static) method gets the instance of `AudioContext`.\n * @return {AudioContext}\n */\n XSound.get = () => {\n return audiocontext;\n };\n\n /**\n * This class (static) method gets `currentTime` property in the instance of `AudioContext`.\n * @return {number}\n */\n XSound.getCurrentTime = () => {\n return audiocontext.currentTime;\n };\n\n /** @override */\n XSound.toString = () => {\n return '[XSound]';\n };\n\n // for Autoplay Policy\n const setup = () => {\n XSound.setup().then(() => {}).catch(() => {});\n\n document.removeEventListener('click', setup, true);\n document.removeEventListener('mousedown', setup, true);\n document.removeEventListener('mouseup', setup, true);\n document.removeEventListener('touchstart', setup, true);\n document.removeEventListener('touchend', setup, true);\n };\n\n document.addEventListener('click', setup, true);\n document.addEventListener('mousedown', setup, true);\n document.addEventListener('mouseup', setup, true);\n document.addEventListener('touchstart', setup, true);\n document.addEventListener('touchend', setup, true);\n} else {\n XSound = () => null;\n\n XSound.IS_XSOUND = IS_XSOUND;\n}\n\n// for `<script>`\nglobal.XSound = XSound;\nglobal.X = XSound; // Alias of `XSound`\n\n// for ESModules and SSR (Server Side Rendering)\nif (typeof exports !== 'undefined') {\n exports.XSound = XSound;\n exports.X = XSound; // Alias of `XSound`\n}\n"],"names":["Connectable","Visualizer","sampleRate","this","isActive","graphics","canvas","context","svg","interval","timerid","styles","element","HTMLCanvasElement","CANVAS","getContext","SVGElement","SVG","key","value","k","String","replace","toLowerCase","v","undefined","parseFloat","shape","wave","grad","Array","isArray","isError","grads","offset","isNaN","Object","prototype","toString","call","prop","test","font","parseInt","data","minDecibels","maxDecibels","drawOnCanvas","drawBySVG","toDataURL","outerHTML","state","Boolean","innerWidth","innerHeight","middle","nPlotInterval","CanvasRenderingContext2D","Float32Array","w","h","m","strokeStyle","lineWidth","width","lineCap","cap","lineJoin","join","beginPath","i","len","length","x","left","y","top","moveTo","lineTo","stroke","fillStyle","upside","gradient","createLinearGradient","gradients","addColorStop","color","fillRect","linearGradientId","path","document","createElementNS","XMLNS","d","setAttribute","defs","createSVGLinearGradient","g","appendChild","rect","linearGradient","stop","size","style","family","height","clearRect","innerHTML","TimeOverview","savedImage","currentTime","sprite","plotInterval","textInterval","isDown","mode","DRAG_MODE_UPDATE","offsetX","startTime","endTime","onStart","bind","onMove","onEnd","arguments","param","r","DRAG_MODE_SPRITE","querySelector","SVG_SPRITE_CLASS_NAME","removeChild","right","bottom","Math","floor","nTextInterval","drawTimeDomainFloat32ArrayOnCanvas","grid","text","t","createFontString","fillText","measureText","trim","getImageData","getAttribute","drawTimeDomainFloat32ArrayBySVG","SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW","textContent","weight","classList","add","SVG_CURRENT_TIME_CLASS_NAME","time","ImageData","putImageData","baseX","abs","baseRect","lastElementChild","previousElementSibling","callback","drawNode","start","move","end","navigator","userAgent","removeEventListener","window","addEventListener","event","type","offsetLeft","parentNode","Element","scrollLeft","update","draw","getOffsetX","preventDefault","pageX","touches","Time","UINT","FLOAT","ceil","SVG_LINEAR_GRADIENT_ID_TIME","FFT","max","mindB","maxdB","range","drawnSize","fsDivN","f","slice","SVG_LINEAR_GRADIENT_ID_FFT","Analyser","analyser","createAnalyser","input","createGain","connect","timeOverviewL","timeOverviewR","fft","fftSize","smoothingTimeConstant","frequencyBinCount","domain","channel","buffer","c","AudioBuffer","numberOfChannels","set","getChannelData","Uint8Array","getByteTimeDomainData","getFloatTimeDomainData","requestAnimationFrame","setTimeout","getByteFrequencyData","getFloatFrequencyData","cancelAnimationFrame","clearTimeout","toUpperCase","Track","trackNumber","dataBlocks","dataBlock","push","Channel","channelNumber","tracks","channelGain","track","gain","Recorder","bufferSize","numberOfInputs","numberOfOutputs","processor","createScriptProcessor","channels","activeTrack","paused","numberOfTracks","n","append","hasTrack","gainL","gainR","trackL","get","trackR","onaudioprocess","inputLs","inputBuffer","inputRs","recordedLs","recordedRs","disconnect","every","hasChannel","some","has","flattenTrack","j","sum","numberOfElements","currentBlock","index","numberOfMaxBlocks","mixedValues","currentTrack","clear","qbit","soundLs","soundRs","mixTrack","flatTrack","CHANNEL","QBIT","SIZE","min","CHUNK_SIZE","RIFF_CHUNK","RATE","BPS","DATA_SIZE","sounds","binary","pow","Int16Array","base64","btoa","map","fromCodePoint","blob","Blob","URL","createObjectURL","Session","sender","BUFFER_SIZE","receiver","websocket","tls","host","port","openCallback","closeCallback","errorCallback","properties","open","close","error","scheme","charAt","p","WebSocket","binaryType","onopen","onclose","onerror","onmessage","ArrayBuffer","total","byteLength","BYTES_PER_ELEMENT","bufferLs","bufferRs","outputLs","outputBuffer","outputRs","destination","isConnected","bufferedAmount","send","readyState","OPEN","stateCallback","waitCallback","intervalid","setInterval","clearInterval","Effector","output","lfo","createOscillator","depth","rate","frequency","noteOn","noteOff","values","isStop","s","stopTime","releaseTime","JSON","stringify","params","Autopanner","panner","createStereoPanner","pan","AutopannerFallback","amplitudeL","amplitudeR","splitter","createChannelSplitter","merger","createChannelMerger","lfoSplitter","inputs","Chorus","delay","createDelay","mix","tone","createBiquadFilter","feedback","delayTime","LOWPASS","Q","SQRT1_2","depthRate","Compressor","compressor","createDynamicsCompressor","threshold","knee","ratio","attack","release","minValues","maxValues","Delay","MAX_DELAY_TIME","dry","wet","Distortion","distortion","createWaveShaper","drive","CLEAN","amount","numberOfSamples","BANDPASS","curve","createCurve","CRUNCH","OVERDRIVE","DISTORTION","FUZZ","curves","a","abx","exp","EnvelopeGenerator","generators","activeIndexes","activeCounter","decay","sustain","AudioNode","t0","t1","t2","t2Value","activeIndex","cancelScheduledValues","setValueAtTime","linearRampToValueAtTime","setTargetAtTime","useCurve","t3","t4","setValueCurveAtTime","setTargetValueAtTime","counter","MIN_GAIN","isDisconnect","generator","Equalizer","bass","treble","presence","LOWSHELF","PEAKING","HIGHSHELF","Filter","filter","maxFrequency","FILTER_TYPES","minFrequnecy","Flanger","Listener","listener","positions","forwards","ups","positionX","AudioParam","positionY","positionZ","z","setPosition","forwardX","forwardY","forwardZ","upX","upY","upZ","setOrientation","Panner","createPanner","orientations","refDistance","maxDistance","rolloffFactor","coneInnerAngle","coneOuterAngle","coneOuterGain","panningModel","HRTF","distanceModel","INVERSE_DISTANCE","orientationX","orientationY","orientationZ","PANNING_MODELS","DISTANCE_MODELS","Phaser","numberOfStages","filters","MAXIMUM_STAGES","ALLPASS","PitchShifter","pitch","realLs","realRs","imagLs","imagRs","arealLs","arealRs","aimagLs","aimagRs","eq","IFFT","reals","imags","pow2","indexes","log2","stage","rest","areal","aimag","breal","bimag","creal","cos","PI","cimag","sin","real","imag","Reverb","isLoadError","rirs","convolver","createConvolver","impulse","decodeAudioData","timeout","successCallback","progressCallback","success","progress","load","url","xhr","XMLHttpRequest","ontimeout","ERROR_AJAX_TIMEOUT","onprogress","abort","ERROR_AJAX","onload","status","arrayBuffer","response","audioBuffer","ERROR_DECODE","responseType","Ringmodulator","amplitude","Stereo","delayL","delayR","Tremolo","WAVE_TYPES","Wah","autoWah","lowpass","envelopeFollower","sensitivity","SoundModule","init","modules","mastervolume","INPUT","recorder","session","forEach","module","OUTPUT","NUMBER_OF_INPUTS","NUMBER_OF_OUTPUTS","stereo","wah","pitchshifter","equalizer","autopanner","tremolo","ringmodulator","phaser","flanger","chorus","reverb","envelopegenerator","name","effector","source","connects","Oscillator","setPeriodicWave","setWaveTable","volume","octave","fine","customs","MAX_SIZE","subarray","periodicWave","createPeriodicWave","OCTAVE","detune","Glide","frequencies","LINEAR","EXPONENTIAL","diff","oscillator","OscillatorModule","sources","times","isAnalyser","glide","states","setGenerator","duration","processCallback","ready","on","off","OneshotModule","resources","buffers","volumes","isStops","settings","transpose","loop","selectedIndex","bufferIndex","playbackRate","loopStart","loopEnd","createBufferSource","noteGrainOn","onended","AudioBufferSourceNode","oneshot","NoiseModule","WHITE_NOISE","PINK_NOISE","BROWNIAN_NOISE","getGenerator","lastOut","random","b0","b1","b2","b3","b4","b5","b6","white","VocalCanceler","dataL","dataR","AudioModule","callbacks","vocalcanceler","setup","b","decode","ended","isBuffer","dataLs","dataRs","createBuffer","copyToChannel","sprites","keys","reduce","audioBuffers","audio","isSource","MediaModule","media","ext","mse","sb","file","mimeType","controls","muted","autoplay","listeners","formats","HTMLAudioElement","AUDIO","HTMLVideoElement","VIDEO","format","canPlayType","MediaElementAudioSourceNode","createMediaElementSource","src","resume","then","catch","Error","loadstart","pause","HTMLMediaElement","isFinite","channelCount","endOfStream","revokeObjectURL","onSourceOpen","onSourceEnded","onSourceClose","onSourceBufferUpdateEnd","onSourceBufferError","MediaSource","isTypeSupported","removeAttribute","indexOf","message","position","play","pos","Promise","resolve","reject","addSourceBuffer","sourceopen","request","Request","fetch","appendBuffer","sourceended","sourceclose","updateend","pictureInPictureEnabled","disablePictureInPicture","pictureInPictureElement","requestPictureInPicture","exitPictureInPicture","NoiseGate","level","NoiseSuppressor","outputs","xreals","ximags","yreals","yimags","amplitudes","phases","sqrt","atan2","StreamModule","stream","constraints","each","noisegate","noisesuppressor","streamCallback","mediaDevices","getUserMedia","MediaStream","runAnalyser","audioTracks","getAudioTracks","createMediaStreamTrackSource","createMediaStreamSource","isStreaming","clearAudio","clearVideo","getVideoTracks","enumerateDevices","MixerModule","ProcessorModule","options","moduleURL","promise","AudioWorkletNode","Map","audioWorklet","addModule","ScriptProcessorNode","postMessage","onmessageerror","parameters","MIDI","midiAccess","sysex","requestMIDIAccess","inputIterator","outputIterator","next","done","o","TokenMap","TokenTypes","Token","token","Tokenizer","mml","tokens","split","reverse","notes","numbers","pop","SPACE","EOS","TEMPO","NOTE","REST","NUMBER","TIE","UNKNOWN","Tree","operator","node","space","indent","getToken","getOperator","TreeConstructor","tokenizer","syntaxTree","nextToken","getType","tree","MMLSyntaxError","ERRORS","concat","Sequence","note","sequence","toPlainObject","Sequencer","treeConstructor","sequences","timeOf4note","trees","parse","getLeft","getRight","getValue","free","leftToken","rightToken","digits","computeIndex","HALF_UP","SHARP","HALF_DOWN","EQUAL_TEMPERAMENT","console","assert","computeFrequency","numberOf4note","QUARTER_NOTE","includes","DOT","current","previous","pitchname","C","D","E","F","G","A","B","R","computedIndex","MIN_A","FREQUENCY_RATIO","Part","currentIndex","currentPosition","sequencer","highlight","prev","MML","parts","mmls","part","asMML","getMML","getSequence","isPaused","hasSequence","getCurrentIndex","setCurrentIndex","X","T","M","L","K","abc","match","totalDuration","shift","splittedNotes","chord","splittedNote","matches","tuplet","chordLength","restNote","read","reader","FileReader","code","NOT_FOUND_ERR","SECURITY_ERR","ABORT_ERR","NOT_READABLE_ERR","ENCODING_ERR","result","readAsArrayBuffer","readAsDataURL","readAsText","XSound","global","AudioContext","webkitAudioContext","WebkitMediaSource","webkitURL","mozURL","webkitRequestAnimationFrame","mozRequestAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","IS_XSOUND","audiocontext","createJavaScriptNode","createGainNode","createDelayNode","createWaveTable","SAMPLE_RATE","ajax","convertTime","exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen","cancelFullScreen","Event","stopPropagation","dataTransfer","files","target","File","requestFullscreen","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","toFrequencies","toTextFile","string","converted","charCode","charCodeAt","toAscii","clone","clones","sourceList","noConflict","deep","getCurrentTime","exports"],"sourceRoot":""}
1
+ {"version":3,"file":"xsound.js","mappings":"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","sources":["webpack://xsound/./src/interfaces/Connectable.js","webpack://xsound/./src/SoundModule/Analyser/Visualizer.js","webpack://xsound/./src/SoundModule/Analyser/TimeOverview.js","webpack://xsound/./src/SoundModule/Analyser/Time.js","webpack://xsound/./src/SoundModule/Analyser/FFT.js","webpack://xsound/./src/SoundModule/Analyser/index.js","webpack://xsound/./src/SoundModule/Recorder/Track.js","webpack://xsound/./src/SoundModule/Recorder/Channel.js","webpack://xsound/./src/SoundModule/Recorder/index.js","webpack://xsound/./src/SoundModule/Session.js","webpack://xsound/./src/SoundModule/Effectors/Effector.js","webpack://xsound/./src/SoundModule/Effectors/Autopanner.js","webpack://xsound/./src/SoundModule/Effectors/AutopannerFallback.js","webpack://xsound/./src/SoundModule/Effectors/Chorus.js","webpack://xsound/./src/SoundModule/Effectors/Compressor.js","webpack://xsound/./src/SoundModule/Effectors/Delay.js","webpack://xsound/./src/SoundModule/Effectors/Distortion.js","webpack://xsound/./src/SoundModule/Effectors/EnvelopeGenerator.js","webpack://xsound/./src/SoundModule/Effectors/Equalizer.js","webpack://xsound/./src/SoundModule/Effectors/Filter.js","webpack://xsound/./src/SoundModule/Effectors/Flanger.js","webpack://xsound/./src/SoundModule/Effectors/Listener.js","webpack://xsound/./src/SoundModule/Effectors/Panner.js","webpack://xsound/./src/SoundModule/Effectors/Phaser.js","webpack://xsound/./src/SoundModule/Effectors/PitchShifter.js","webpack://xsound/./src/SoundModule/Effectors/Reverb.js","webpack://xsound/./src/SoundModule/Effectors/Ringmodulator.js","webpack://xsound/./src/SoundModule/Effectors/Stereo.js","webpack://xsound/./src/SoundModule/Effectors/Tremolo.js","webpack://xsound/./src/SoundModule/Effectors/Wah.js","webpack://xsound/./src/SoundModule/index.js","webpack://xsound/./src/OscillatorModule/Oscillator.js","webpack://xsound/./src/OscillatorModule/Glide.js","webpack://xsound/./src/OscillatorModule/index.js","webpack://xsound/./src/OneshotModule/index.js","webpack://xsound/./src/NoiseModule/index.js","webpack://xsound/./src/AudioModule/VocalCanceler.js","webpack://xsound/./src/AudioModule/index.js","webpack://xsound/./src/MediaModule/index.js","webpack://xsound/./src/StreamModule/NoiseGate.js","webpack://xsound/./src/StreamModule/NoiseSuppressor.js","webpack://xsound/./src/StreamModule/index.js","webpack://xsound/./src/MixerModule/index.js","webpack://xsound/./src/ProcessorModule/index.js","webpack://xsound/./src/MIDI/index.js","webpack://xsound/./src/MML/Token.js","webpack://xsound/./src/MML/Tokenizer.js","webpack://xsound/./src/MML/Tree.js","webpack://xsound/./src/MML/TreeConstructor.js","webpack://xsound/./src/MML/Sequence.js","webpack://xsound/./src/MML/Sequencer.js","webpack://xsound/./src/MML/Part.js","webpack://xsound/./src/MML/index.js","webpack://xsound/./src/XSound/index.js","webpack://xsound/./src/main.js"],"sourcesContent":["'use strict';\n\n/**\n * This interface defines behaviors for connection to `AudioNode`.\n * @interface\n */\nexport class Connectable {\n /**\n * for input\n */\n INPUT() {}\n\n /**\n * for output\n */\n OUTPUT() {}\n}\n","'use strict';\n\n/**\n * This private class defines the properties that subclasses (`TimeOverview`, `Time`, `FFT`) require.\n * @constructor\n */\nexport class Visualizer {\n static CANVAS = 'canvas';\n static SVG = 'svg';\n\n static XMLNS = 'http://www.w3.org/2000/svg';\n static XLINK = 'http://www.w3.org/1999/xlink';\n\n static SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW = 'svg-linear-gradient-time-overview';\n static SVG_LINEAR_GRADIENT_ID_TIME = 'svg-linear-gradient-time';\n static SVG_LINEAR_GRADIENT_ID_FFT = 'svg-linear-gradient-fft';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n this.sampleRate = sampleRate;\n\n this.isActive = false;\n\n // either 'canvas' or 'svg'\n this.graphics = '';\n\n // in the case of using Canvas\n this.canvas = null;\n this.context = null;\n\n // in the case of using SVG\n this.svg = null;\n\n // for timer\n this.interval = 1000;\n this.timerid = null;\n\n this.styles = {\n 'shape' : 'line',\n 'grad' : [\n {\n 'offset' : 0,\n 'color' : 'rgba(0, 128, 255, 1.0)'\n },\n {\n 'offset' : 1,\n 'color' : 'rgba(0, 0, 255, 1.0)'\n }\n ],\n 'wave' : 'rgba(0, 0, 255, 1.0)',\n 'grid' : 'rgba(255, 0, 0, 1.0)',\n 'text' : 'rgba(255, 255, 255, 1.0)',\n 'font' : {\n 'family' : 'Arial',\n 'size' : '13px',\n 'style' : 'normal'\n },\n 'width' : 1.5,\n 'cap' : 'round',\n 'join' : 'miter',\n 'top' : 15,\n 'right' : 30,\n 'bottom' : 15,\n 'left' : 30\n };\n }\n\n /**\n * This method sets up for using Canvas or SVG.\n * @param {HTMLCanvasElement|SVGElement} element This argument is either `HTMLCanvasElement` or `SVGElement`.\n * @return {Visualizer} This is returned for method chain.\n */\n setup(element) {\n if (element instanceof HTMLCanvasElement) {\n this.graphics = Visualizer.CANVAS;\n this.canvas = element;\n this.context = this.canvas.getContext('2d');\n } else if (element instanceof SVGElement) {\n this.graphics = Visualizer.SVG;\n this.svg = element;\n\n // this.svg.setAttribute('xmlns', Visualizer.XMLNS);\n // this.svg.setAttribute('xmlns:xlink', Visualizer.XLINK);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {string|number|Array.<object>} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {string|number|Array.<object>} This is returned as the value of designated property in the case of getter.\n */\n param(key, value) {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'interval':\n if (value === undefined) {\n return this.interval;\n }\n\n if (String(value).toLowerCase() === 'auto') {\n this.interval = 'auto';\n } else {\n v = parseFloat(value);\n\n if (v >= 0) {\n this.interval = v;\n }\n }\n\n break;\n case 'shape':\n if (value === undefined) {\n return this.styles.shape;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === 'line') || (v === 'rect')) {\n this.styles.shape = (this.styles.wave !== 'gradient') ? v : 'rect';\n }\n\n break;\n case 'grad':\n if (value === undefined) {\n return this.styles.grad;\n }\n\n if (!Array.isArray(value)) {\n value = [value];\n }\n\n let isError = false;\n\n for (const grads of value) {\n if (('offset' in grads) && ('color' in grads)) {\n const offset = parseFloat(grads.offset);\n\n if (isNaN(offset) || (offset < 0) || (offset > 1)) {\n isError = true;\n break;\n }\n } else {\n isError = true;\n break;\n }\n }\n\n if (!isError) {\n this.styles.grad = value;\n }\n\n break;\n case 'font':\n if (value === undefined) {\n return this.styles[k];\n }\n\n if (Object.prototype.toString.call(value) === '[object Object]') {\n for (const prop in value) {\n if (/(?:family|size|style)/i.test(prop)) {\n this.styles.font[prop] = String(value[prop]);\n }\n }\n }\n\n break;\n case 'wave':\n case 'grid':\n case 'text':\n case 'cap' :\n case 'join':\n if (value === undefined) {\n return this.styles[k];\n }\n\n if (typeof value === 'string') {\n if ((k === 'wave') && (value === 'gradient')) {\n this.styles.shape = 'rect';\n }\n\n this.styles[k] = value.toLowerCase();\n }\n\n break;\n case 'width' :\n case 'top' :\n case 'right' :\n case 'bottom':\n case 'left' :\n if (value === undefined) {\n return this.styles[k];\n }\n\n v = (k === 'width') ? parseFloat(value) : parseInt(value, 10);\n\n if (v >= 0) {\n this.styles[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n /**\n * This method draws sound wave to Canvas or SVG. This method conceals difference of API for drawing.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is parameter for spectrum. The default value is -100 dB.\n * @param {number} maxDecibels This argument is parameter for spectrum. The default value is -30 dB.\n * @return {Visualizer} This is returned for method chain.\n */\n start(data, minDecibels, maxDecibels) {\n switch (this.graphics) {\n case Visualizer.CANVAS:\n this.drawOnCanvas(data, minDecibels, maxDecibels);\n break;\n case Visualizer.SVG:\n this.drawBySVG(data, minDecibels, maxDecibels);\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method creates string for `Data URL` or `HTML` for the drawn figure.\n * @return {string|Visualizer} This is returned as `Data URL` or `HTML` string. If `setup` method has not been invoked, this is returned for method chain.\n */\n create() {\n switch (this.graphics) {\n case Visualizer.CANVAS:\n return this.canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');\n case Visualizer.SVG:\n return this.svg.outerHTML;\n default:\n return this;\n }\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Visualizer} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n return this;\n }\n\n /**\n * This method draws time domain data of `Float32Array` to Canvas.\n * @param {CanvasRenderingContext2D} context This argument is the instance of `CanvasRenderingContext2D`.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is the width of drawing area.\n * @param {number} innerHeight This argument is the height of drawing area.\n * @param {number} middle This argument is the middle of drawing area.\n * @param {number} nPlotInterval This argument is the interval of drawing.\n */\n drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, nPlotInterval) {\n if (!(context instanceof CanvasRenderingContext2D)) {\n return this;\n }\n\n if (!(data instanceof Float32Array)) {\n return this;\n }\n\n let w = parseInt(innerWidth, 10);\n let h = parseInt(innerHeight, 10);\n let m = parseInt(middle, 10);\n\n if (isNaN(w)) { w = 0; }\n if (isNaN(h)) { h = 0; }\n if (isNaN(m)) { m = 0; }\n\n // Begin drawing\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = ((1 - data[i]) * (h / 2)) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = -1 * (data[i] * (h / 2));\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = (innerHeight / 2) + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, m, this.styles.width, y);\n }\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method draws time domain data of `Float32Array` to SVG.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is the width of drawing area.\n * @param {number} innerHeight This argument is the height of drawing area.\n * @param {number} middle This argument is the middle of drawing area.\n * @param {number} nPlotInterval This argument is the interval of drawing.\n * @param {string} linearGradientId This argument is id attribute for `SVGLinearGradientElement`.\n * @return {SVGPathElement|SVGGElement} This is returned as `SVGElement`.\n */\n drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, nPlotInterval, linearGradientId) {\n let w = parseInt(innerWidth, 10);\n let h = parseInt(innerHeight, 10);\n let m = parseInt(middle, 10);\n\n if (isNaN(w)) { w = 0; }\n if (isNaN(h)) { h = 0; }\n if (isNaN(m)) { m = 0; }\n\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const x = ((i / len) * w) + this.styles.left;\n const y = ((1 - data[i]) * (h / 2)) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n return path;\n case 'rect':\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(linearGradientId);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0, len = data.length; i < len; i++) {\n if ((nPlotInterval === null) || (nPlotInterval === undefined) || ((i % nPlotInterval) === 0)) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((i / len) * w) + this.styles.left;\n const y = data[i] * (innerHeight / 2);\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', m);\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${m})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${linearGradientId})`);\n\n g.appendChild(rect);\n }\n }\n\n return g;\n default:\n return null;\n }\n }\n\n /**\n * This method creates elements for SVG linear gradient.\n * @param {string} linearGradientId This argument is id attribute for `SVGLinearGradientElement`.\n * @return {SVGDefsElement} This is returned as the instance of `SVGDefsElement`.\n */\n createSVGLinearGradient(linearGradientId) {\n const defs = document.createElementNS(Visualizer.XMLNS, 'defs');\n const linearGradient = document.createElementNS(Visualizer.XMLNS, 'linearGradient');\n\n linearGradient.setAttribute('id', String(linearGradientId));\n linearGradient.setAttribute('x1', '0%');\n linearGradient.setAttribute('y1', '0%');\n linearGradient.setAttribute('x2', '0%');\n linearGradient.setAttribute('y2', '100%');\n\n for (const gradients of this.styles.grad) {\n const stop = document.createElementNS(Visualizer.XMLNS, 'stop');\n\n stop.setAttribute('offset', gradients.offset);\n stop.setAttribute('stop-color', gradients.color);\n\n linearGradient.appendChild(stop);\n }\n\n defs.appendChild(linearGradient);\n\n return defs;\n }\n\n /**\n * This method creates string for font.\n * @return {string} This is returned as string for font.\n */\n createFontString() {\n const { size, style, family } = this.styles.font;\n\n return `${style} ${size} \"${family}\"`;\n }\n\n /** @abstract */\n drawOnCanvas() {\n return this;\n }\n\n /** @abstract */\n drawBySVG() {\n return this;\n }\n\n /**\n * This method clears graphics.\n */\n clear() {\n if (this.context) {\n const { width, height } = this.canvas;\n\n this.context.clearRect(0, 0, width, height);\n }\n\n if (this.svg) {\n this.svg.innerHTML = '';\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser Visualizer]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing audio wave in overview of time domain.\n * @constructor\n * @extends {Visualizer}\n */\nexport class TimeOverview extends Visualizer {\n static SVG_CURRENT_TIME_CLASS_NAME = 'xsound-svg-current-time';\n static SVG_SPRITE_CLASS_NAME = 'xsound-svg-sprite';\n static DRAG_MODE_UPDATE = 'update';\n static DRAG_MODE_SPRITE = 'sprite';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = null;\n this.length = 0;\n\n this.currentTime = 'rgba(0, 0, 0, 0.5)'; // This style is used for the rectangle that displays current time of audio\n this.sprite = 'rgba(255, 255, 255, 0.25)'; // This style is used for the rectangle that displays sprite range\n this.plotInterval = 0.0625; // Draw wave at intervals of this value [sec]\n this.textInterval = 60; // Draw text at intervals of this value [sec]\n\n this.isDown = false;\n\n this.mode = TimeOverview.DRAG_MODE_UPDATE; // or 'sprite'\n\n this.offsetX = 0;\n this.startTime = 0;\n this.endTime = 0;\n\n this.onStart = this.onStart.bind(this);\n this.onMove = this.onMove.bind(this);\n this.onEnd = this.onEnd.bind(this);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'currenttime':\n if (value === undefined) {\n return this.currentTime;\n }\n\n this.currentTime = String(value).toLowerCase();\n\n break;\n case 'sprite':\n if (value === undefined) {\n return this.sprite;\n }\n\n this.sprite = String(value).toLowerCase();\n\n break;\n case 'plotinterval':\n case 'textinterval':\n if (value === undefined) {\n return this[k.replace('interval', 'Interval')];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k.replace('interval', 'Interval')] = v;\n }\n\n break;\n case 'mode':\n if (value === undefined) {\n return this.mode;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === TimeOverview.DRAG_MODE_UPDATE) || (v === TimeOverview.DRAG_MODE_SPRITE)) {\n this.mode = v;\n\n // Clear for Audio Sprite\n this.offsetX = 0;\n this.startTime = 0;\n this.endTime = 0;\n\n if (this.svg instanceof SVGElement) {\n const rect = this.svg.querySelector(`.${TimeOverview.SVG_SPRITE_CLASS_NAME}`);\n\n if (rect instanceof SVGElement) {\n this.svg.removeChild(rect);\n }\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws audio wave in overview of time domain to Canvas.\n * @param {Float32Array} data This argument is data for drawing.\n * @return {TimeOverview} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw wave at intervals of `this.plotInterval`\n const nPlotInterval = Math.floor(this.plotInterval * this.sampleRate);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n this.drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, nPlotInterval);\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.floor((i / this.sampleRate) / 60)} min`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n }\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = context.getImageData(0, 0, width, height);\n this.length = data.length;\n\n // This rectangle displays current time of audio\n context.fillStyle = this.currentTime;\n context.fillRect(this.styles.left, this.styles.top, 1, innerHeight);\n\n return this;\n }\n\n /**\n * This method draws audio wave in overview of time domain to SVG.\n * @param {Float32Array} data This argument is data for drawing.\n * @return {TimeOverview} This is returned for method chain.\n * @override\n */\n drawBySVG(data) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw wave at intervals of `this.plotInterval`\n const nPlotInterval = Math.floor(this.plotInterval * this.sampleRate);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin drawing\n svg.appendChild(this.drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, nPlotInterval, Visualizer.SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW));\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / len) * innerWidth) + this.styles.left;\n const t = Math.floor((i / this.sampleRate) / 60) + ' min';\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // This rectangle displays current time of audio\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.classList.add(TimeOverview.SVG_CURRENT_TIME_CLASS_NAME);\n\n rect.setAttribute('y', (this.styles.top + 1));\n rect.setAttribute('height', (innerHeight - 1));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.currentTime);\n\n svg.appendChild(rect);\n\n // for `TimeOverview#update`, `TimeOverview#drag`\n this.savedImage = svg;\n this.length = data.length;\n\n return this;\n }\n\n /**\n * This method draws current time of audio on Canvas or SVG.\n * @param {number} time This argument is current time of audio.\n * @return {TimeOverview} This is returned for method chain.\n */\n update(time) {\n const t = parseFloat(time);\n\n if (isNaN(t) || (t < 0)) {\n return this;\n }\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n if (this.savedImage instanceof ImageData) {\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const x = ((t * this.sampleRate) / this.length) * innerWidth;\n\n context.clearRect(0, 0, width, height);\n context.putImageData(this.savedImage, 0, 0);\n\n if (this.mode === TimeOverview.DRAG_MODE_UPDATE) {\n context.fillStyle = this.currentTime;\n context.fillRect(this.styles.left, (this.styles.top + 1), x, (innerHeight - 1));\n } else if (this.mode === TimeOverview.DRAG_MODE_SPRITE) {\n if (this.endTime !== 0) {\n const baseX = Math.floor(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.length) * innerWidth);\n context.fillStyle = this.sprite;\n\n if (x >= this.offsetX) {\n context.fillRect((this.styles.left + this.offsetX), (this.styles.top + 1), baseX, (innerHeight - 1));\n } else {\n context.fillRect((this.styles.left + this.offsetX - baseX), (this.styles.top + 1), baseX, (innerHeight - 1));\n }\n }\n\n context.fillStyle = this.currentTime;\n\n if (x >= this.offsetX) {\n context.fillRect((this.styles.left + this.offsetX), (this.styles.top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n } else {\n context.fillRect((this.styles.left + x), (this.styles.top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n }\n }\n }\n\n break;\n case Visualizer.SVG:\n const rect = this.svg.querySelector(`.${TimeOverview.SVG_CURRENT_TIME_CLASS_NAME}`);\n\n if (rect instanceof SVGElement) {\n const width = parseInt(this.svg.getAttribute('width'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const x = ((t * this.sampleRate) / this.length) * innerWidth;\n\n if (this.mode === TimeOverview.DRAG_MODE_UPDATE) {\n rect.setAttribute('x', this.styles.left);\n rect.setAttribute('width', x);\n // rect.setAttribute('transform', `translate(${x} 0)`);\n rect.setAttribute('aria-label', 'current time');\n } else if (this.mode === TimeOverview.DRAG_MODE_SPRITE) {\n if (this.endTime !== 0) {\n const baseRect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n baseRect.classList.add(TimeOverview.SVG_SPRITE_CLASS_NAME);\n\n if (this.svg.lastElementChild.previousElementSibling instanceof SVGElement) {\n this.svg.removeChild(this.svg.lastElementChild.previousElementSibling);\n }\n\n const baseX = Math.floor(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.length) * innerWidth);\n\n baseRect.setAttribute('y', (this.styles.top + 1));\n baseRect.setAttribute('height', rect.getAttribute('height'));\n baseRect.setAttribute('stroke', 'none');\n baseRect.setAttribute('fill', this.sprite);\n baseRect.setAttribute('aria-label', 'current time');\n\n if (x >= this.offsetX) {\n baseRect.setAttribute('x', (this.styles.left + this.offsetX));\n } else {\n baseRect.setAttribute('x', (this.styles.left + this.offsetX - baseX));\n }\n\n baseRect.setAttribute('width', baseX);\n\n this.svg.appendChild(baseRect);\n this.svg.appendChild(rect);\n }\n\n if (x >= this.offsetX) {\n rect.setAttribute('x', (this.styles.left + this.offsetX));\n } else {\n rect.setAttribute('x', (this.styles.left + x));\n }\n\n rect.setAttribute('width', Math.abs(x - this.offsetX));\n rect.setAttribute('aria-label', 'sprite time');\n }\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method registers event listener for setting current time by drag.\n * @param {function} callback This argument is invoked when current time is changed.\n * @return {TimeOverview} This is returned for method chain.\n */\n drag(callback) {\n let drawNode = null;\n\n let start = '';\n let move = '';\n let end = '';\n\n // Touch Panel ?\n if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) {\n start = 'touchstart';\n move = 'touchmove';\n end = 'touchend';\n } else {\n start = 'mousedown';\n move = 'mousemove';\n end = 'mouseup';\n }\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n drawNode = this.canvas;\n break;\n case Visualizer.SVG:\n drawNode = this.svg;\n break;\n default:\n return this;\n }\n\n this.callback = Object.prototype.toString.call(callback) === '[object Function]' ? callback : () => {};\n\n drawNode.removeEventListener(start, this.onStart, true);\n drawNode.removeEventListener(move, this.onMove, true);\n window.removeEventListener(end, this.onEnd, true);\n\n drawNode.addEventListener(start, this.onStart, true);\n drawNode.addEventListener(move, this.onMove, true);\n window.addEventListener(end, this.onEnd, true);\n\n return this;\n }\n\n /**\n * This method draws the rectangle for current time of audio.\n * @param {Event} event This argument is the instance of `Event`.\n * @param {number} offsetX This argument is X coordinate on Canvas or SVG.\n * @param {function} callback This argument is invoked when the rectangle is drawn.\n * @return {TimeOverview} This is returned for method chain.\n */\n draw(event, type, offsetX) {\n let offsetLeft = 0;\n let width = 0;\n\n switch (this.graphics) {\n case Visualizer.CANVAS:\n offsetLeft = this.canvas.offsetLeft;\n width = this.canvas.width;\n break;\n case Visualizer.SVG:\n offsetLeft = this.svg.parentNode.offsetLeft;\n width = parseInt(this.svg.getAttribute('width'), 10);\n break;\n default:\n break;\n }\n\n let x = offsetX - (offsetLeft + this.styles.left);\n\n if (this.canvas.parentNode instanceof Element) {\n x += this.canvas.parentNode.scrollLeft;\n }\n\n width -= (this.styles.left + this.styles.right);\n\n // Exceed ?\n if (x < 0) { x = 0; }\n if (x > width) { x = width; }\n\n const plot = (x / width) * this.length;\n const time = plot / this.sampleRate;\n\n if ((type === 'mousedown') || (type === 'touchstart')) {\n this.offsetX = x;\n this.startTime = time;\n this.endTime = 0;\n }\n\n if ((type === 'mouseup') || (type === 'touchend')) {\n this.endTime = time;\n }\n\n this.update(time);\n\n if (this.startTime <= time) {\n this.callback(event, this.startTime, time, this.mode, true);\n } else if (this.startTime > time) {\n this.callback(event, time, this.startTime, this.mode, false);\n }\n\n return this;\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onStart(event) {\n this.draw(event, event.type, this.getOffsetX(event));\n this.isDown = true;\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onMove(event) {\n if (!this.isDown) {\n return;\n }\n\n event.preventDefault(); // for Touch Panel\n this.draw(event, event.type, this.getOffsetX(event));\n }\n\n /**\n * This method is event listener for drawing the rectangle.\n * @param {Event} event This argument is the instance of `Event`.\n */\n onEnd(event) {\n if (!this.isDown) {\n return;\n }\n\n this.draw(event, event.type, this.getOffsetX(event));\n\n this.isDown = false;\n }\n\n /**\n * This method returns X coordinate from `Event` object.\n * @param {Event} event This argument is the instance of `Event`.\n * @return {number} This is returned as X coordinate.\n */\n getOffsetX(event) {\n if (event.pageX) {\n return event.pageX;\n }\n\n if (event.touches[0]) {\n return event.touches[0].pageX;\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser TimeOverview]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing sound wave in time domain.\n * @constructor\n * @extends {Visualizer}\n */\nexport class Time extends Visualizer {\n static UINT = 'uint';\n static FLOAT = 'float';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n this.type = Time.UINT; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\n this.textInterval = 0.005; // Draw text at intervals this value [sec]\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === Time.UINT) || (v === Time.FLOAT)) {\n this.type = v;\n }\n\n break;\n case 'textinterval':\n if (value === undefined) {\n return this.textInterval;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.textInterval = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in time domain to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @return {Time} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n switch (this.type) {\n case Time.FLOAT:\n this.drawTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle);\n break;\n case Time.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = (0.5 - (data[i] / 255)) * innerHeight;\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = (innerHeight / 2) + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, middle, this.styles.width, y);\n }\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.ceil((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.ceil((i / this.sampleRate) * 1000)} ms`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in time domain to SVG.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @return {Time} This is returned for method chain.\n * @override\n */\n drawBySVG(data) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n const middle = Math.floor(innerHeight / 2) + this.styles.top;\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval * this.sampleRate);\n\n // Begin drawing\n svg.innerHTML = '';\n\n // Begin drawing\n switch (this.type) {\n case Time.FLOAT:\n svg.appendChild(this.drawTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, null, Visualizer.SVG_LINEAR_GRADIENT_ID_TIME));\n break;\n case Time.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0, len = data.length; i < len; i++) {\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case 'rect':\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(Visualizer.SVG_LINEAR_GRADIENT_ID_TIME);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0, len = data.length; i < len; i++) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((i / len) * innerWidth) + this.styles.left;\n const y = ((data[i] / 255) - 0.5) * innerHeight;\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', middle);\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${Visualizer.SVG_LINEAR_GRADIENT_ID_TIME})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.ceil((i / len) * innerWidth) + this.styles.left;\n const t = `${Math.ceil((i / this.sampleRate) * 1000)} ms`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n const texts = ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = Math.floor((1 - parseFloat(t.trim())) * (innerHeight / 2)) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser Time]';\n }\n}\n","'use strict';\n\nimport { Visualizer } from './Visualizer';\n\n/**\n * This private class defines properties for drawing sound wave in frequency domain (spectrum).\n * @constructor\n * @extends {Visualizer}\n */\nexport class FFT extends Visualizer {\n static UINT = 'uint';\n static FLOAT = 'float';\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n */\n constructor(sampleRate) {\n super(sampleRate);\n\n this.type = FFT.UINT; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\n this.size = 256; // Range for drawing\n this.textInterval = 1000; // Draw text at intervals of this value [Hz]\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === FFT.UINT) || (v === FFT.FLOAT)) {\n this.type = v;\n }\n\n break;\n case 'size':\n if (value === undefined) {\n return this.size;\n }\n\n v = parseInt(value, 10);\n min = 0;\n max = 1024; // `AnalyserNode#fftSize` max 2048 -> half 1024\n\n if ((v > min) && (v <= max)) {\n this.size = v;\n }\n\n break;\n case 'textinterval':\n if (value === undefined) {\n return this.textInterval;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.textInterval = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in frequency domain (spectrum) to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is in order to determine the range of drawing. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine the range of drawing. The default value is -30 dB.\n * @return {FFT} This is returned for method chain.\n * @override\n */\n drawOnCanvas(data, minDecibels, maxDecibels) {\n if (!((this.canvas instanceof HTMLCanvasElement) && this.isActive)) {\n return this;\n }\n\n const mindB = parseFloat(minDecibels);\n const maxdB = parseFloat(maxDecibels);\n\n const range = maxdB - mindB;\n\n const context = this.context;\n\n const { width, height } = this.canvas;\n\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n\n const drawnSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const fsDivN = this.sampleRate / (2 * data.length);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval / fsDivN);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin drawing\n switch (this.type) {\n case FFT.FLOAT:\n // Set style\n context.strokeStyle = (this.styles.wave !== 'gradient') ? this.styles.wave : 'rgba(0, 0, 255, 1.0)'; // line only\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n // Draw wave\n context.beginPath();\n\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = (Math.abs(data[i] - maxdB) * (innerHeight / range)) + this.styles.top; // [dB] * [px / dB] = [px]\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case FFT.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Set style\n context.strokeStyle = this.styles.wave;\n context.lineWidth = this.styles.width;\n context.lineCap = this.styles.cap;\n context.lineJoin = this.styles.join;\n\n context.beginPath();\n\n // Draw wave\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = ((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n context.moveTo((x + (this.styles.width / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n case 'rect':\n // Set style\n if (this.styles.wave !== 'gradient') {\n context.fillStyle = this.styles.wave;\n }\n\n // Draw wave\n for (let i = 0; i < drawnSize; i++) {\n const x = ((i / drawnSize) * innerWidth) + this.styles.left;\n const y = -1 * ((data[i] / 255) * innerHeight);\n\n // Set style\n if (this.styles.wave === 'gradient') {\n const upside = innerHeight + this.styles.top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.grad) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n }\n\n context.fillRect(x, (innerHeight + this.styles.top), this.styles.width, y);\n }\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0; i < drawnSize; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n\n const f = Math.floor(this.textInterval * (i / nTextInterval));\n const t = (f < 1000) ? `${f} Hz` : `${String(f / 1000).slice(0, 3)} kHz`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(x, this.styles.top, 1, innerHeight);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n }\n }\n }\n\n // Draw grid and text (Y axis)\n switch (this.type) {\n case FFT.FLOAT:\n for (let i = mindB; i <= maxdB; i += 10) {\n const t = `${i} dB`;\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = Math.floor(((-1 * (i - maxdB)) / range) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n\n break;\n case FFT.UINT:\n default:\n const texts = ['0.00', '0.25', '0.50', '0.75', '1.00'];\n\n for (const t of texts) {\n const x = Math.floor(this.styles.left - context.measureText(t).width);\n const y = ((1 - parseFloat(t)) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n context.fillStyle = this.styles.grid;\n context.fillRect(this.styles.left, y, innerWidth, 1);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n context.fillStyle = this.styles.text;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method draws sound wave in frequency domain (spectrum) to SVG.\n * @param {Uint8Array|Float32Array} data This argument is data for drawing.\n * @param {number} minDecibels This argument is in order to determine the range of drawing. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine the range of drawing. The default value is -30 dB.\n * @return {FFT} This is returned for method chain.\n * @override\n */\n drawBySVG(data, minDecibels, maxDecibels) {\n if (!((this.svg instanceof SVGElement) && this.isActive)) {\n return this;\n }\n\n const mindB = parseFloat(minDecibels);\n const maxdB = parseFloat(maxDecibels);\n\n const range = maxdB - mindB;\n\n const svg = this.svg;\n\n const width = parseInt(svg.getAttribute('width'), 10);\n const height = parseInt(svg.getAttribute('height'), 10);\n const innerWidth = width - (this.styles.left + this.styles.right);\n const innerHeight = height - (this.styles.top + this.styles.bottom);\n\n const drawnSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (sample rate / FFT size)\n const fsDivN = this.sampleRate / (2 * data.length);\n\n // Draw text at intervals of `this.textInterval`\n const nTextInterval = Math.floor(this.textInterval / fsDivN);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin drawing\n switch (this.type) {\n case FFT.FLOAT:\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0; i < drawnSize; i++) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor(-1 * (data[i] - maxdB) * (innerHeight / range)) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', ((this.styles.wave !== 'gradient') ? this.styles.wave : 'rgba(0, 0, 255, 1.0)')); // line only\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case FFT.UINT:\n default:\n switch (this.styles.shape) {\n case 'line':\n // Draw wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let i = 0; i < drawnSize; i++) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor((1 - (data[i] / 255)) * innerHeight) + this.styles.top;\n\n if (i === 0) {\n d += `M${x + (this.styles.width / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', this.styles.wave);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', this.styles.width);\n path.setAttribute('stroke-linecap', this.styles.cap);\n path.setAttribute('stroke-linejoin', this.styles.join);\n\n svg.appendChild(path);\n\n break;\n case 'rect':\n // Draw wave\n let defs = null;\n\n if (this.styles.wave === 'gradient') {\n defs = this.createSVGLinearGradient(Visualizer.SVG_LINEAR_GRADIENT_ID_FFT);\n }\n\n // Draw wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let i = 0; i < drawnSize; i++) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n const y = Math.floor((data[i] / 255) * innerHeight);\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', (this.styles.top + innerHeight));\n rect.setAttribute('width', this.styles.width);\n\n if (y < 0) {\n rect.setAttribute('height', -y);\n } else {\n rect.setAttribute('height', y);\n rect.setAttribute('transform', `rotate(180 ${x + (this.styles.width / 2)} ${this.styles.top + innerHeight})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? this.styles.wave : `url(#${Visualizer.SVG_LINEAR_GRADIENT_ID_FFT})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n default:\n break;\n }\n\n break;\n }\n\n if ((this.styles.grid !== 'none') || (this.styles.text !== 'none')) {\n // Draw grid and text (X axis)\n for (let i = 0; i < drawnSize; i++) {\n if ((i % nTextInterval) === 0) {\n const x = Math.floor((i / drawnSize) * innerWidth) + this.styles.left;\n\n const f = Math.floor(this.textInterval * (i / nTextInterval));\n const t = (f < 1000) ? `${f} Hz` : `${String(f / 1000).slice(0, 3)} kHz`;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', this.styles.top);\n rect.setAttribute('width', 1);\n rect.setAttribute('height', innerHeight);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (this.styles.top + innerHeight + parseInt(this.styles.font.size, 10)));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n }\n\n // Draw grid and text (Y axis)\n switch (this.type) {\n case FFT.FLOAT:\n for (let i = mindB; i <= maxdB; i += 10) {\n const t = `${i}dB`;\n const x = this.styles.left;\n const y = Math.floor(((-1 * (i - maxdB)) / range) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n\n break;\n case FFT.UINT:\n default:\n const texts = ['0.00', '0.25', '0.50', '0.75', '1.00'];\n\n for (const t of texts) {\n const x = this.styles.left;\n const y = ((1 - parseFloat(t)) * innerHeight) + this.styles.top;\n\n // Draw grid\n if (this.styles.grid !== 'none') {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n rect.setAttribute('x', x);\n rect.setAttribute('y', y);\n rect.setAttribute('width', innerWidth);\n rect.setAttribute('height', 1);\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', this.styles.grid);\n\n svg.appendChild(rect);\n }\n\n // Draw text\n if (this.styles.text !== 'none') {\n const text = document.createElementNS(Visualizer.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x);\n text.setAttribute('y', (y - Math.floor(parseInt(this.styles.font.size, 10) / 4)));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', this.styles.text);\n text.setAttribute('font-family', this.styles.font.family);\n text.setAttribute('font-size', this.styles.font.size);\n text.setAttribute('font-style', this.styles.font.style);\n text.setAttribute('font-weight', this.styles.font.weight);\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser FFT]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\nimport { TimeOverview } from './TimeOverview';\nimport { Time } from './Time';\nimport { FFT } from './FFT';\n\n/**\n * This private class manages 3 private classes (`TimeOverview`, `Time`, `FFT`) for drawing sound wave.\n * @constructor\n */\nexport class Analyser extends Connectable {\n /**\n * @param {AudioContext} context This argument is This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n super();\n\n this.analyser = context.createAnalyser();\n this.input = context.createGain();\n\n // GainNode (Input) -> AnalyserNode\n this.input.connect(this.analyser);\n\n this.timeOverviewL = new TimeOverview(context.sampleRate);\n this.timeOverviewR = new TimeOverview(context.sampleRate);\n this.time = new Time(context.sampleRate);\n this.fft = new FFT(context.sampleRate);\n\n // Set default value\n this.analyser.fftSize = 2048;\n this.analyser.minDecibels = -100;\n this.analyser.maxDecibels = -30;\n this.analyser.smoothingTimeConstant = 0.8;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Analyser} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'fftsize':\n if (value === undefined) {\n return this.analyser.fftSize;\n }\n\n v = parseInt(value, 10);\n\n switch (v) {\n case 32:\n case 64:\n case 128:\n case 256:\n case 512:\n case 1024:\n case 2048:\n this.analyser.fftSize = v;\n break;\n default:\n break;\n }\n\n break;\n case 'frequencybincount':\n return this.analyser.frequencyBinCount; // Getter only\n case 'mindecibels':\n if (value === undefined) {\n return this.analyser.minDecibels;\n }\n\n v = parseFloat(value);\n max = -30;\n\n if (v < max) {\n this.analyser.minDecibels = v;\n }\n\n break;\n case 'maxdecibels':\n if (value === undefined) {\n return this.analyser.maxDecibels;\n }\n\n v = parseFloat(value);\n min = -100;\n\n if (v > min) {\n this.analyser.maxDecibels = v;\n }\n\n break;\n case 'smoothingtimeconstant':\n if (value === undefined) {\n return this.analyser.smoothingTimeConstant;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.analyser.smoothingTimeConstant = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method creates data for drawing and executes drawing.\n * @param {string} domain This argument is one of 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @param {number} channel This argument is number greater than or equal to 0.\n * @param {AudioBuffer} buffer This argument is the instance of `AudioBuffer`. The data for drawing audio wave in overview of time domain is gotten from this argument.\n * @return {Analyser} This is returned for method chain.\n */\n start(domain, channel, buffer) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n const c = parseInt(channel, 10);\n\n let data = null;\n\n switch (d) {\n case 'timeoverview':\n switch (c) {\n case 0:\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > c) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(c));\n this.timeOverviewL.start(data);\n }\n }\n\n break;\n case 1:\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > c) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(c));\n this.timeOverviewR.start(data);\n }\n }\n\n break;\n default:\n break;\n }\n\n break;\n case 'timeoverviewl':\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > 0) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(0));\n this.timeOverviewL.start(data);\n }\n }\n\n break;\n case 'timeoverviewr':\n if (buffer instanceof AudioBuffer) {\n if (buffer.numberOfChannels > 1) {\n data = new Float32Array(buffer.length);\n data.set(buffer.getChannelData(1));\n this.timeOverviewR.start(data);\n }\n }\n\n break;\n case 'time':\n if (this.time.param('type') === 'uint') {\n data = new Uint8Array(this.analyser.fftSize);\n this.analyser.getByteTimeDomainData(data);\n this.time.start(data);\n } else {\n data = new Float32Array(this.analyser.fftSize);\n this.analyser.getFloatTimeDomainData(data);\n this.time.start(data);\n }\n\n if (this.time.param('interval') === 'auto') {\n this.time.timerid = window.requestAnimationFrame(() => {\n this.start(domain);\n });\n } else {\n this.time.timerid = window.setTimeout(() => {\n this.start(domain);\n }, this.time.param('interval'));\n }\n\n break;\n case 'fft':\n if (this.fft.param('type') === 'uint') {\n data = new Uint8Array(this.analyser.frequencyBinCount);\n this.analyser.getByteFrequencyData(data);\n this.fft.start(data);\n } else {\n data = new Float32Array(this.analyser.frequencyBinCount);\n this.analyser.getFloatFrequencyData(data);\n this.fft.start(data, this.analyser.minDecibels, this.analyser.maxDecibels);\n }\n\n if (this.fft.param('interval') === 'auto') {\n this.fft.timerid = window.requestAnimationFrame(() => {\n this.start(domain);\n });\n } else {\n this.fft.timerid = window.setTimeout(() => {\n this.start(domain);\n }, this.fft.param('interval'));\n }\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method stops drawing.\n * @param {string} domain This argument is one of 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @return {Analyser} This is returned for method chain.\n */\n stop(domain) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n\n switch (d) {\n case 'timeoverviewl':\n case 'timeoverviewr':\n break;\n case 'time':\n if (this.time.param('interval') === 'auto') {\n window.cancelAnimationFrame(this.time.timerid);\n } else {\n window.clearTimeout(this.time.timerid);\n }\n\n this.time.timerid = null;\n\n break;\n case 'fft':\n if (this.fft.param('interval') === 'auto') {\n window.cancelAnimationFrame(this.fft.timerid);\n } else {\n window.clearTimeout(this.fft.timerid);\n }\n\n this.fft.timerid = null;\n\n break;\n default:\n break;\n }\n\n return this;\n }\n\n /**\n * This method selects domain for drawing.\n * @param {string} domain This argument is one of 'timeoverview', 'timeOverviewL', 'timeOverviewR', 'time', 'fft'.\n * @param {number} channel This argument is number greater than or equal to 0.\n * @return {TimeOverview|Time|FFT|Analyser} This value is the instance of selected class.\n */\n domain(domain, channel) {\n const d = String(domain).replace(/-/g, '').toLowerCase();\n const c = parseInt(channel, 10);\n\n switch (d) {\n case 'timeoverview':\n switch (c) {\n case 0:\n return this.timeOverviewL;\n case 1:\n return this.timeOverviewR;\n default:\n return this;\n }\n case 'timeoverviewl':\n case 'timeoverviewr':\n return this[`timeOverview${d.slice(-1).toUpperCase()}`];\n case 'time':\n case 'fft' :\n return this[d];\n default:\n return this;\n }\n }\n\n /**\n * This method gets the instance of `AnalyserNode`.\n * @return {AnalyserNode}\n */\n get() {\n return this.analyser;\n }\n\n /** @override */\n get INPUT() {\n return this.input;\n }\n\n /** @override */\n get OUTPUT() {\n return this.input;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Analyser]';\n }\n}\n","'use strict';\n\n/**\n * This class is model for a recording track.\n * Namely, this class has the recorded sound data.\n * @constructor\n */\nexport class Track {\n /**\n * @param {number} trackNumber This argument is a track number greater than or equal to 0.\n */\n constructor(trackNumber) {\n this.trackNumber = trackNumber >= 0 ? trackNumber : 0;\n this.dataBlocks = []; /** @type {Array.<Float32Array>} */\n }\n\n /**\n * This method returns the array that contains the recorded sound data.\n * @return {Array.<Float32Array>} This is returned as the array that contains `Float32Array`.\n */\n get() {\n return this.dataBlocks;\n }\n\n /**\n * This method appends the recorded sound data as `Float32Array`\n * @param {Float32Array} dataBlock This argument is the instance of `Float32Array` that has the recorded sound data.\n */\n append(dataBlock) {\n if (dataBlock instanceof Float32Array) {\n this.dataBlocks.push(dataBlock);\n }\n }\n\n /**\n * This method determines whether contains the recorded sound data.\n * @return {boolean} If the track has the recorded data, this value is `true`. Otherwise, this value is `false`.\n */\n has() {\n return this.dataBlocks.length > 0;\n }\n\n /**\n * This method clears data blocks.\n */\n clear() {\n this.dataBlocks.length = 0;\n }\n}\n","'use strict';\n\nimport { Track } from './Track';\n\n/**\n * This class is model for a recording channel.\n * @constructor\n */\nexport class Channel {\n /**\n * @param {number} channelNumber This argument is a channel number greater than or equal to 0.\n */\n constructor(channelNumber) {\n this.channelNumber = channelNumber >= 0 ? channelNumber : 0;\n\n this.tracks = []; /** @type {Array.<Float32Array>} */\n this.channelGain = 1;\n }\n\n /**\n * This method returns the designated track or the array that contains tracks.\n * @param {number} trackNumber This argument is the target track number.\n * @return {Track|Array.<Track>} This is returned as the designated track or the array that contains the instances of `Track`.\n */\n get(trackNumber) {\n const t = parseInt(trackNumber, 10);\n\n if ((t >= 0) && (t < this.tracks.length)) {\n return this.tracks[t];\n }\n\n return this.tracks;\n }\n\n /**\n * This method appends the instance of `Track`.\n * @param {Track} track This argument is the instance of `Track` as a recording track.\n */\n append(track) {\n if (track instanceof Track) {\n this.tracks.push(track);\n }\n }\n\n /**\n * This method returns the number of tracks.\n * @return {number} This is returned as the number of tracks.\n */\n length() {\n return this.tracks.length;\n }\n\n /**\n * This method gets or sets the channel gain.\n * @param {number} gain This argument is the channel gain. If this argument is omitted, This method is getter.\n * @return {number} This is returned as the channel gain in the case of getter.\n */\n gain(gain) {\n if (gain === undefined) {\n return this.channelGain;\n }\n\n const g = parseFloat(gain);\n\n if ((g >= 0) && (g <= 1)) {\n this.channelGain = g;\n }\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\nimport { Track } from './Track';\nimport { Channel } from './Channel';\n\n/**\n * This private class defines properties for multi track recording.\n * @constructor\n */\nexport class Recorder extends Connectable {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @param {number} numberOfInputs This argument is the number of inputs for `ScriptProcessorNode`.\n * @param {number} numberOfOutputs This argument the number of outputs for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize, numberOfInputs, numberOfOutputs) {\n super();\n\n this.sampleRate = context.sampleRate;\n\n this.context = context;\n this.processor = context.createScriptProcessor(bufferSize, numberOfInputs, numberOfOutputs);\n\n this.channels = [];\n\n this.activeTrack = -1; // There is not any active track in the case of -1\n this.paused = true; // for preventing from the duplicate `onaudioprocess` event (`start` method)\n }\n\n /**\n * This method sets the max number of tracks.\n * @param {number} numberOfTracks This argument is the number of channels (not used currently). The default value is 2.\n * @param {number} numberOfTracks This argument is the max number of tracks. The default value is 1.\n * @return {Recorder} This is returned for method chain.\n */\n setup(numberOfChannels, numberOfTracks) {\n const n = parseInt(numberOfTracks, 10);\n const t = n > 0 ? n : 1;\n\n this.channels.push(new Channel(0));\n this.channels.push(new Channel(1));\n\n for (const channel of this.channels) {\n for (let i = 0; i < t; i++) {\n channel.append(new Track(i));\n }\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Recorder} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n switch (k) {\n case '0' :\n case 'left':\n if (value === undefined) {\n return this.channels[0].gain();\n }\n\n this.channels[0].gain(value);\n break;\n case '1' :\n case 'right':\n if (value === undefined) {\n return this.channels[1].gain();\n }\n\n this.channels[1].gain(value);\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method selects active track.\n * @param {number} trackNumber This argument is in order to select active track.\n * @return {Recorder} This is returned for method chain.\n */\n ready(trackNumber) {\n if (this.hasTrack(trackNumber)) {\n this.activeTrack = trackNumber;\n } else {\n this.activeTrack = -1;\n }\n\n return this;\n }\n\n /**\n * This method starts recording. If there is not any active track, this method stops `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Recorder} This is returned for method chain.\n */\n start() {\n if ((this.activeTrack !== -1) && this.paused) {\n this.paused = false;\n\n const gainL = this.channels[0].gain();\n const gainR = this.channels[1].gain();\n\n const trackL = this.channels[0].get(this.activeTrack);\n const trackR = this.channels[1].get(this.activeTrack);\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n if (this.activeTrack !== -1) {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n\n const recordedLs = new Float32Array(bufferSize);\n const recordedRs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n recordedLs[i] = gainL * inputLs[i];\n recordedRs[i] = gainR * inputRs[i];\n }\n\n trackL.append(recordedLs);\n trackR.append(recordedRs);\n } else {\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method turns off the all of tracks, and stops `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Recorder} This is returned for method chain.\n */\n stop() {\n this.activeTrack = -1; // Flag becomes inactive\n this.paused = true;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n return this;\n }\n\n /**\n * This method determines whether the designated channel number is valid.\n * @param {number} channelNumber This argument is channel number for validation.\n * @return {boolean} If the designated channel is valid range, this value is `true`. Otherwise, this value is `false`.\n */\n hasChannel(channelNumber) {\n const c = parseInt(channelNumber, 10);\n\n return (c >= 0) && (c < this.channels.length);\n }\n\n /**\n * This method determines whether the designated track number is valid.\n * @param {number} trackNumber This argument is track number for validation.\n * @return {boolean} If the designated track is valid range, this value is `true`. Otherwise, this value is `false`.\n */\n hasTrack(trackNumber) {\n const t = parseInt(trackNumber, 10);\n\n return (t >= 0) && this.channels.every(channel => t < channel.length());\n }\n\n /**\n * This method determines whether the track has a recorded data.\n * @param {number} channelNumber This argument is the target channel number.\n * @param {number} trackNumber This argument is the target track number.\n * @return {boolean} If there is the track that has a recorded data at least, this method returns true. Otherwise this value is `false`.\n */\n has(channelNumber, trackNumber) {\n if (!this.hasChannel(channelNumber)) {\n return this.channels.some(channel => {\n const tracks = channel.get();\n\n return tracks.some(track => track.has());\n });\n }\n\n const c = parseInt(channelNumber, 10);\n\n const tracks = this.channels[c].get();\n\n if (!this.hasTrack(trackNumber)) {\n return tracks.some(track => track.has());\n }\n\n const t = parseInt(trackNumber, 10);\n\n return tracks[t].has();\n }\n\n /**\n * This method determines whether active track exists.\n * @return {number} This is returned as active track.\n */\n get() {\n return this.activeTrack;\n }\n\n /**\n * This method flats recorded sounds in track.\n * @param {number} channelNumber This argument is the channel number for mixing.\n * @param {number} trackNumber This argument is track number.\n * @return {Float32Array} This is returned as array for flatten sound.\n */\n flatTrack(channelNumber, trackNumber) {\n if (!this.hasChannel(channelNumber) || !this.hasTrack(trackNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const track = channel.get(trackNumber);\n const dataBlocks = track.get();\n const bufferSize = this.processor.bufferSize;\n\n const flattenTrack = new Float32Array(dataBlocks.length * bufferSize);\n\n for (let i = 0, len = dataBlocks.length; i < len; i++) {\n const dataBlock = dataBlocks[i];\n\n for (let j = 0; j < bufferSize; j++) {\n flattenTrack[(i * bufferSize) + j] = dataBlock[j];\n }\n }\n\n return flattenTrack;\n }\n\n /**\n * This method synthesizes recorded sounds in track.\n * @param {number} channelNumber This argument is the channel number for mixing.\n * @return {Float32Array} This is returned as array for synthesized sound.\n */\n mixTrack(channelNumber) {\n if (!this.hasChannel(channelNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const tracks = channel.get();\n const bufferSize = this.processor.bufferSize;\n\n let sum = 0;\n let numberOfElements = 0;\n let currentBlock = 0;\n let index = 0;\n\n // Calculate sound data size\n let numberOfMaxBlocks = 0;\n\n // Search the max number of `Float32Array`'s each track\n for (const track of tracks) {\n const dataBlocks = track.get();\n\n if (numberOfMaxBlocks < dataBlocks.length) {\n numberOfMaxBlocks = dataBlocks.length;\n }\n }\n\n const mixedValues = new Float32Array(numberOfMaxBlocks * bufferSize);\n\n while (true) {\n for (let currentTrack = 0, len = tracks.length; currentTrack < len; currentTrack++) {\n const track = tracks[currentTrack];\n const dataBlocks = track.get();\n const dataBlock = dataBlocks[currentBlock];\n\n if (dataBlock instanceof Float32Array) {\n sum += dataBlock[index];\n numberOfElements++;\n }\n }\n\n if (numberOfElements <= 0) {\n return mixedValues;\n }\n\n const offset = currentBlock * bufferSize;\n\n // Average\n mixedValues[offset + index] = sum / numberOfElements;\n\n // Clear\n sum = 0;\n numberOfElements = 0;\n\n // Next data\n if (index < (bufferSize - 1)) {\n // Next element in Float32Array\n index++;\n } else {\n // Next Float32Array\n currentBlock++;\n index = 0;\n }\n }\n }\n\n /**\n * This method clears recorded sound of the designated track.\n * @param {number} trackNumber This argument is track for clearing.\n * @return {Recorder} This is returned for method chain.\n */\n clear(trackNumber) {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n const t = parseInt(trackNumber, 10);\n\n if (t === -1) {\n for (const channel of this.channels) {\n const tracks = channel.get();\n\n for (const track of tracks) {\n track.clear();\n }\n }\n } else {\n if (this.hasTrack(t)) {\n for (const channel of this.channels) {\n const track = channel.get(t);\n\n track.clear();\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method creates WAVE file as Object URL or Data URL.\n * @param {number} trackNumber This argument is the track number for mixing.\n * @param {number} numberOfChannels This argument is in order to select stereo or monaural of WAVE file. The default value is 2.\n * @param {number} qbit This argument is quantization bit of PCM. The default value is 16 (bit).\n * @param {string} type This argument is one of 'blob', 'objecturl', 'base64', 'dataurl'.\n * @return {Blob|string} This is returned as `Blob` or Object URL or Base64 or Data URL for WAVE file.\n */\n create(trackNumber, numberOfChannels, qbit, type) {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n /** @type {Float32Array} */\n let soundLs = null;\n\n /** @type {Float32Array} */\n let soundRs = null;\n\n if ((trackNumber === -1) && this.has()) {\n soundLs = this.mixTrack(0);\n soundRs = this.mixTrack(1);\n } else if (this.has(0, trackNumber) && this.has(1, trackNumber)) {\n soundLs = this.flatTrack(0, trackNumber);\n soundRs = this.flatTrack(1, trackNumber);\n } else {\n // Sound data does not exists\n return '';\n }\n\n // PCM parameters\n const CHANNEL = (numberOfChannels === 1) ? 1 : 2;\n const QBIT = (qbit === 8) ? 8 : 16;\n const SIZE = (CHANNEL === 1) ? Math.min(soundLs.length, soundRs.length) : (2 * Math.min(soundLs.length, soundRs.length));\n\n // Parameters for WAVE file\n const FMT_CHUNK = 28;\n const DATA_CHUNK = 8 + (SIZE * (QBIT / 8));\n const CHUNK_SIZE = 36 + (SIZE * (QBIT / 8));\n const RIFF_CHUNK = 8 + (FMT_CHUNK + DATA_CHUNK);\n const RATE = this.sampleRate;\n const BPS = RATE * CHANNEL * (QBIT / 8);\n const DATA_SIZE = SIZE * (QBIT / 8);\n\n /** @type {Uint8Array|Int16Array} */\n let sounds = null;\n\n switch (QBIT) {\n case 8:\n sounds = new Uint8Array(SIZE);\n\n for (let i = 0; i < SIZE; i++) {\n // Convert 8 bit unsigned integer (-1 -> 0, 0 -> 128, 1 -> 255)\n let binary = 0;\n\n if ((i % CHANNEL) === 0) {\n binary = ((soundLs[Math.floor(i / CHANNEL)] + 1) / 2) * (Math.pow(2, 8) - 1); // Left channel\n } else {\n binary = ((soundRs[Math.floor(i / CHANNEL)] + 1) / 2) * (Math.pow(2, 8) - 1); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (Math.pow(2, 8) - 1)) { binary = (Math.pow(2, 8) - 1); }\n if (binary < (Math.pow(2, 0) - 1)) { binary = (Math.pow(2, 0) - 1); }\n\n sounds[i] = binary;\n }\n\n break;\n case 16:\n sounds = new Int16Array(SIZE);\n\n for (let i = 0; i < SIZE; i++) {\n // Convert 16 bit integer (-1 -> -32768, 0 -> 0, 1 -> 32767)\n let binary = 0;\n\n if ((i % CHANNEL) === 0) {\n binary = soundLs[Math.floor(i / CHANNEL)] * Math.pow(2, 15); // Left channel\n } else {\n binary = soundRs[Math.floor(i / CHANNEL)] * Math.pow(2, 15); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (+Math.pow(2, 15) - 1)) { binary = +Math.pow(2, 15) - 1; }\n if (binary < (-Math.pow(2, 15) - 0)) { binary = -Math.pow(2, 15) - 0; }\n\n sounds[i] = binary;\n }\n\n break;\n default:\n break;\n }\n\n const wave = new Uint8Array(44 + DATA_SIZE);\n\n wave[0] = 0x52; // 'R'\n wave[1] = 0x49; // 'I'\n wave[2] = 0x46; // 'F'\n wave[3] = 0x46; // 'F'\n\n wave[4] = (CHUNK_SIZE >> 0) & 0xFF;\n wave[5] = (CHUNK_SIZE >> 8) & 0xFF;\n wave[6] = (CHUNK_SIZE >> 16) & 0xFF;\n wave[7] = (CHUNK_SIZE >> 24) & 0xFF;\n\n wave[8] = 0x57; // 'W'\n wave[9] = 0x41; // 'A'\n wave[10] = 0x56; // 'V'\n wave[11] = 0x45; // 'E'\n\n // fmt chunk\n wave[12] = 0x66; // 'f'\n wave[13] = 0x6D; // 'm'\n wave[14] = 0x74; // 't'\n wave[15] = 0x20; // ' '\n\n wave[16] = 16;\n wave[17] = 0;\n wave[18] = 0;\n wave[19] = 0;\n\n wave[20] = 1;\n wave[21] = 0;\n\n // fmt chunk -> Channels (Monaural or Stereo)\n wave[22] = CHANNEL;\n wave[23] = 0;\n\n // fmt chunk -> Sample rate\n wave[24] = (RATE >> 0) & 0xFF;\n wave[25] = (RATE >> 8) & 0xFF;\n wave[26] = (RATE >> 16) & 0xFF;\n wave[27] = (RATE >> 24) & 0xFF;\n\n // fmt chunk -> Byte per second\n wave[28] = (BPS >> 0) & 0xFF;\n wave[29] = (BPS >> 8) & 0xFF;\n wave[30] = (BPS >> 16) & 0xFF;\n wave[31] = (BPS >> 24) & 0xFF;\n\n // fmt chunk -> Block size\n wave[32] = CHANNEL * (QBIT / 8);\n wave[33] = 0;\n\n // fmt chunk -> Byte per Sample\n wave[34] = QBIT;\n wave[35] = 0;\n\n // data chunk\n wave[36] = 0x64; // 'd'\n wave[37] = 0x61; // 'a'\n wave[38] = 0x74; // 't\n wave[39] = 0x61; // 'a'\n\n wave[40] = (DATA_SIZE >> 0) & 0xFF;\n wave[41] = (DATA_SIZE >> 8) & 0xFF;\n wave[42] = (DATA_SIZE >> 16) & 0xFF;\n wave[43] = (DATA_SIZE >> 24) & 0xFF;\n\n for (let i = 0; i < SIZE; i++) {\n switch (QBIT) {\n case 8:\n wave[(RIFF_CHUNK - DATA_SIZE) + i] = sounds[i];\n break;\n case 16:\n // The byte order in WAVE file is little endian\n wave[(RIFF_CHUNK - DATA_SIZE) + (2 * i) + 0] = ((sounds[i] >> 0) & 0xFF);\n wave[(RIFF_CHUNK - DATA_SIZE) + (2 * i) + 1] = ((sounds[i] >> 8) & 0xFF);\n break;\n default:\n break;\n }\n }\n\n const t = String(type).toLowerCase();\n\n // Create WAVE file (Object URL or Data URL)\n const base64 = window.btoa(Array.from(wave).map(d => String.fromCodePoint(d)).join(''));\n const blob = new Blob([wave], { 'type' : 'audio/wav' });\n\n switch (t) {\n case 'base64' :\n case 'dataurl':\n if (t === 'base64') {\n return base64;\n }\n\n return `data:audio/wav;base64,${base64}`;\n case 'blob' :\n case 'objecturl':\n default :\n if (t === 'blob') {\n return blob;\n }\n\n return window.URL.createObjectURL(blob);\n }\n }\n\n /** @override */\n get INPUT() {\n return this.processor;\n }\n\n /** @override */\n get OUTPUT() {\n return this.processor;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Recorder]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../interfaces/Connectable';\n\n/**\n * This private class defines properties for sound session on network.\n * @constructor\n */\nexport class Session extends Connectable {\n static BUFFER_SIZE = 2048;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @param {number} numberOfInputs This argument is the number of inputs for `ScriptProcessorNode`.\n * @param {number} numberOfOutputs This argument the number of outputs for `ScriptProcessorNode`.\n * @param {Analyser} analyser This argument is the instance of `Analyser`.\n */\n constructor(context, bufferSize, numberOfInputs, numberOfOutputs, analyser) {\n super();\n\n this.isActive = false;\n\n this.context = context;\n this.analyser = analyser; // the instance of `Analyser`\n\n // HACK: Fix buffer size on different environments\n this.sender = context.createScriptProcessor(Session.BUFFER_SIZE, numberOfInputs, numberOfOutputs);\n this.receiver = context.createScriptProcessor(Session.BUFFER_SIZE, numberOfInputs, numberOfOutputs);\n\n this.websocket = null; // for the instance of `WebSocket`\n this.paused = true; // for preventing from the duplicate `onaudioprocess` event (`start` method)\n }\n\n /**\n * This method creates the instance of `WebSocket` and registers event handlers.\n * @param {boolean} tls This argument is in order to select protocol (either `wss` or `ws`).\n * @param {string} host This argument is server's hostname.\n * @param {number} port This argument is port number for connection.\n * @param {string} path This argument is file that is executed in server side.\n * @param {function} openCallback This argument is invoked as `onopen` event handler in the instance of `WebSocket`.\n * @param {function} closeCallback This argument is invoked as `onclose` event handler in the instance of `WebSocket`.\n * @param {function} errorCallback This argument is invoked as `onerror` event handler in the instance of `WebSocket`.\n * @return {Session} This is returned for method chain.\n */\n setup(tls, host, port, path, openCallback, closeCallback, errorCallback) {\n /*\n if (!navigator.onLine) {\n // Clear\n this.isActive = false;\n this.paused = true;\n this.connect();\n this.websocket = null;\n\n throw new Error('Now Offline.');\n }\n */\n\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('tls' in properties) {\n tls = properties.tls;\n }\n\n if ('host' in properties) {\n host = properties.host;\n }\n\n if ('port' in properties) {\n port = properties.port;\n }\n\n if ('path' in properties) {\n path = properties.path;\n }\n\n if ('open' in properties) {\n openCallback = properties.open;\n }\n\n if ('close' in properties) {\n closeCallback = properties.close;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n }\n\n const scheme = tls ? 'wss://' : 'ws://';\n\n if (path.charAt(0) !== '/') {\n path = `/${path}`;\n }\n\n const p = parseInt(port, 10);\n\n if (isNaN(p) || (p < 0) || (p > 65535)) {\n return this;\n }\n\n this.websocket = new WebSocket(`${scheme}${host}:${p}${path}`);\n this.websocket.binaryType = 'arraybuffer';\n\n this.websocket.onopen = event => {\n if (Object.prototype.toString.call(openCallback) === '[object Function]') {\n openCallback(event);\n }\n };\n\n this.websocket.onclose = event => {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n\n if (Object.prototype.toString.call(closeCallback) === '[object Function]') {\n closeCallback(event);\n }\n };\n\n this.websocket.onerror = event => {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event);\n }\n };\n\n this.websocket.onmessage = event => {\n if (!this.isActive) {\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n return;\n }\n\n if (event.data instanceof ArrayBuffer) {\n const total = event.data.byteLength / Float32Array.BYTES_PER_ELEMENT;\n const length = Math.floor(total / 2);\n const offset = length * Float32Array.BYTES_PER_ELEMENT;\n\n const bufferLs = new Float32Array(event.data, 0, length); // Get Left channel data\n const bufferRs = new Float32Array(event.data, offset, length); // Get Right channel data\n\n // Start drawing sound wave\n this.analyser.start('time');\n this.analyser.start('fft');\n\n this.receiver.onaudioprocess = event => {\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (bufferLs instanceof Float32Array) { outputLs.set(bufferLs); }\n if (bufferRs instanceof Float32Array) { outputRs.set(bufferRs); }\n\n // bufferLs = null;\n // bufferRs = null;\n\n if (!this.isActive || (this.websocket === null)) {\n this.analyser.stop('time');\n this.analyser.stop('fft');\n }\n };\n }\n };\n\n return this;\n }\n\n /**\n * This method connects nodes according to state.\n * @return {Session} This is returned for method chain.\n */\n connect() {\n // Clear connection\n this.receiver.disconnect(0);\n this.sender.disconnect(0);\n\n this.receiver.onaudioprocess = null;\n this.sender.onaudioprocess = null;\n\n if (this.isActive) {\n // ScriptProcessorNode (Input) -> Analyser\n this.receiver.connect(this.analyser.input);\n\n // ScriptProcessorNode (Input) -> AudioDestinationNode (Output)\n this.receiver.connect(this.context.destination);\n } else {\n this.paused = true;\n }\n\n return this;\n }\n\n /**\n * This method sends sound data to server.\n * @return {Session} This is returned for method chain.\n */\n start() {\n if (this.isActive && this.isConnected() && this.paused) {\n this.paused = false;\n\n const bufferSize = this.sender.bufferSize;\n\n this.sender.onaudioprocess = event => {\n if (this.isActive && this.isConnected()) {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n\n const buffer = new Float32Array(2 * bufferSize);\n const offset = parseInt((buffer.length / 2), 10);\n\n for (let i = 0; i < bufferSize; i++) {\n buffer[i] = inputLs[i];\n buffer[offset + i] = inputRs[i];\n }\n\n if (this.websocket.bufferedAmount === 0) {\n this.websocket.send(buffer);\n }\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method closes connection to server and destroys the instance of `WebSocket`.\n * @return {Session} This is returned for method chain.\n */\n close() {\n if (this.websocket instanceof WebSocket) {\n this.isActive = false;\n this.paused = true;\n\n this.connect();\n this.websocket.close();\n\n this.websocket = null;\n }\n\n return this;\n }\n\n /**\n * This method determines whether there is the connection to server.\n * @return {boolean} If the connection to server exists, this value is `true`. Otherwise, this value is `false`.\n */\n isConnected() {\n return (this.websocket instanceof WebSocket) && (this.websocket.readyState === WebSocket.OPEN);\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @param {function} stateCallback This argument is invoked when `bufferedAmount` equals to 0.\n * @param {function} waitCallback This argument is invoked until `bufferedAmount` equals to 0.\n * @return {Session} This is returned for method chain.\n */\n state(state, stateCallback, waitCallback) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (Object.prototype.toString.call(waitCallback) === '[object Function]') {\n waitCallback();\n }\n\n const intervalid = window.setInterval(() => {\n if ((this.websocket instanceof WebSocket) && (this.websocket.bufferedAmount !== 0)) {\n return;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n this.connect();\n\n if (Object.prototype.toString.call(stateCallback) === '[object Function]') {\n stateCallback();\n }\n\n window.clearInterval(intervalid);\n }, 10);\n\n return this;\n }\n\n /**\n * This method gets the instance of `WebSocket`.\n * @return {WebSocket}\n */\n get() {\n return this.websocket;\n }\n\n /** @override */\n get INPUT() {\n return this.sender;\n }\n\n /** @override */\n get OUTPUT() {\n return this.sender;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Session]';\n }\n}\n","'use strict';\n\nimport { Connectable } from '../../interfaces/Connectable';\n\n/**\n * This private class defines common properties for effector classes.\n * @constructor\n */\nexport class Effector extends Connectable {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super();\n\n this.isActive = true;\n\n this.context = context;\n\n // for connecting external node\n this.input = context.createGain();\n this.output = context.createGain();\n\n // for LFO (Low Frequency Oscillator)\n // LFO changes parameter cyclically\n this.lfo = context.createOscillator();\n this.depth = context.createGain();\n this.rate = this.lfo.frequency;\n this.processor = context.createScriptProcessor(bufferSize, 2, 2);\n\n // for legacy browsers\n this.lfo.start = this.lfo.start || this.lfo.noteOn;\n this.lfo.stop = this.lfo.stop || this.lfo.noteOff;\n\n this.values = {};\n\n this.isStop = true;\n }\n\n /**\n * This abstract method gets or sets parameter.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Effector} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @abstract\n */\n param() {\n return this;\n }\n\n /**\n * This abstract method connects nodes according to state.\n * @return {Effector} This is returned for method chain.\n * @abstract\n */\n connect() {\n return this;\n }\n\n /**\n * This method starts LFO. Namely, this method starts effector.\n * @param {number} startTime This argument is in order to schedule parameter.\n * @return {Effector} This is returned for method chain.\n */\n start(startTime) {\n if (this.isActive && this.isStop) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.lfo.start(s);\n this.isStop = false;\n }\n\n return this;\n }\n\n /**\n * This method stops LFO, and creates the instance of `OscillatorNode` again.\n * @param {number} stopTime This argument is in order to schedule parameter.\n * @param {number} releaseTime This argument is in order to schedule parameter when it is necessary to consider release time.\n * @return {Effector} This is returned for method chain.\n */\n stop(stopTime, releaseTime) {\n if (this.isActive && !this.isStop) {\n let s = parseFloat(stopTime);\n let r = parseFloat(releaseTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n if (isNaN(r) || (r < 0)) {\n r = 0;\n }\n\n // for saving value\n const type = this.lfo.type;\n const rate = this.lfo.frequency.value;\n\n // Destroy the instance of `OscillatorNode`\n this.lfo.stop(s + r);\n\n // Create the instance of `OscillatorNode` again\n this.lfo = this.context.createOscillator();\n\n // for legacy browsers\n this.lfo.start = this.lfo.start || this.lfo.noteOn;\n this.lfo.stop = this.lfo.stop || this.lfo.noteOff;\n\n // Set the saved value\n this.lfo.type = type;\n this.lfo.frequency.value = rate;\n\n this.rate = this.lfo.frequency;\n\n this.isStop = true;\n }\n\n return this;\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Effector} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n // Start LFO\n this.start(this.context.currentTime);\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n * @abstract\n */\n params() {\n return {};\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n * @abstract\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n get INPUT() {\n return this.input;\n }\n\n /** @override */\n get OUTPUT() {\n return this.output;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Effector]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Autopanner extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.panner = context.createStereoPanner();\n\n // Initialize parameters\n this.panner.pan.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Autopanner` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (pan)\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.panner.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> StereoPannerNode -> GainNode (Output)\n this.input.connect(this.panner);\n this.panner.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Autopanner]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class AutopannerFallback extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitudeL = context.createGain();\n this.amplitudeR = context.createGain();\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createChannelMerger(2);\n\n this.amplitudeL.gain.value = 1; // 1 +- depth\n this.amplitudeR.gain.value = 1; // 1 +- depth\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `AutopannerFallback` is not connected by default\n this.state(false);\n\n // LFO\n this.lfoSplitter = context.createChannelSplitter(2);\n\n // OscillatorNode (LFO) -> GainNode (Depth) -> ScriptProcessorNode -> ChannelSplitterNode -> AudioParam (gain) (L) / (R)\n this.lfo.connect(this.depth);\n this.depth.connect(this.processor);\n this.processor.connect(this.lfoSplitter);\n this.lfoSplitter.connect(this.amplitudeL.gain, 0);\n this.lfoSplitter.connect(this.amplitudeR.gain, 1);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitudeL.disconnect(0);\n this.amplitudeR.disconnect(0);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> ChannelSplitterNode -> GainNode (L) / (R) -> ChannelMergerNode -> GainNode (Output)\n this.input.connect(this.splitter);\n this.splitter.connect(this.amplitudeL, 0, 0);\n this.splitter.connect(this.amplitudeR, 1, 0);\n this.amplitudeL.connect(this.merger, 0, 0);\n this.amplitudeR.connect(this.merger, 0, 1);\n this.merger.connect(this.output);\n } else {\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start(startTime) {\n if (this.isActive && this.isStop) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.lfo.start(s);\n this.isStop = false;\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n const inputs = event.inputBuffer.getChannelData(0);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.depth.gain.value !== 0) && (this.rate.value !== 0)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = inputs[i];\n outputRs[i] = -inputs[i];\n }\n } else {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = 0;\n outputRs[i] = 0;\n }\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.processor);\n this.processor.connect(this.lfoSplitter);\n this.lfoSplitter.connect(this.amplitudeL.gain, 0);\n this.lfoSplitter.connect(this.amplitudeR.gain, 1);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule AutopannerFallback]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Chorus extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay();\n this.mix = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Chorus` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (elayTime)\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.delay.delayTime.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.mix.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive) {\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Chorus]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Compressor extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.compressor = context.createDynamicsCompressor();\n\n // Set default value\n this.compressor.threshold.value = -24;\n this.compressor.knee.value = 30;\n this.compressor.ratio.value = 12;\n this.compressor.attack.value = 0.003;\n this.compressor.release.value = 0.25;\n\n // `Compressor` is connected by default\n this.state(true);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n if (k in this.compressor) {\n if (value === undefined) {\n return this.compressor[k].value;\n }\n\n const v = parseFloat(value);\n\n const minValues = {\n 'threshold' : -100,\n 'knee' : 0,\n 'ratio' : 1,\n 'attack' : 0,\n 'release' : 0\n };\n\n const maxValues = {\n 'threshold' : 0,\n 'knee' : 40,\n 'ratio' : 20,\n 'attack' : 1,\n 'release' : 1\n };\n\n const min = minValues[k];\n const max = maxValues[k];\n\n if ((v >= min) && (v <= max)) {\n this.compressor[k].value = v;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.compressor.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n // GainNode (Input) -> DynamicsCompressorNode -> GainNode (Output)\n this.input.connect(this.compressor);\n this.compressor.connect(this.output);\n } else {\n // Effect OFF\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'threshold' : this.compressor.threshold.value,\n 'knee' : this.compressor.knee.value,\n 'ratio' : this.compressor.ratio.value,\n 'attack' : this.compressor.attack.value,\n 'release' : this.compressor.release.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Compressor]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Delay extends Effector {\n static MAX_DELAY_TIME = 5; // Max delay time is 5000 [ms]\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay(Delay.MAX_DELAY_TIME);\n this.dry = context.createGain();\n this.wet = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n\n // `Delay` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = Delay.MAX_DELAY_TIME;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n }\n\n break;\n case 'dry' :\n case 'wet' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Dry) -> GainNode (Output)\n this.input.connect(this.dry);\n this.dry.connect(this.output);\n\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Wet) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.wet);\n this.wet.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'dry' : this.dry.gain.value,\n 'wet' : this.wet.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Delay]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Distortion extends Effector {\n static CLEAN = 'clean';\n static CRUNCH = 'crunch';\n static OVERDRIVE = 'overdrive';\n static DISTORTION = 'distortion';\n static FUZZ = 'fuzz';\n\n /**\n * This class (static) method creates the instance of `Float32Array` for distortion.\n * @param {string} type This argument is one of 'clean', 'crunch', 'overdrive', 'distortion', 'fuzz'.\n * @param {number} amount This argument is the depth of distortion.\n * @param {number} numberOfSamples This argument is the size of `Float32Array`.\n * @return {Float32Array|null} This is `curve` property in `WaveShaperNode`.\n */\n static createCurve(type, amount, numberOfSamples) {\n // This algorithms are from https://github.com/Theodeus/tuna/blob/master/tuna.js#L1301,L1359\n if ((amount > 0) && (amount < 1)) {\n const curves = new Float32Array(numberOfSamples);\n\n let x = 0;\n let y = 0;\n let a = 0;\n let k = 0;\n let abx = 0;\n\n switch (type) {\n case Distortion.CRUNCH:\n a = 1 - amount > 0.99 ? 0.99 : 1 - amount;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n abx = Math.abs(x);\n\n if (abx < a) {\n y = abx;\n } else if (abx > a) {\n y = a + (abx - a) / (1 + Math.pow((abx - a) / (1 - a), 2));\n } else if (abx > 1) {\n y = abx;\n }\n\n curves[i] = (x === 0 ? 1 : Math.abs(x) / x) * y * (1 / ((a + 1) / 2));\n }\n\n /*\n const a = 2 + Math.round(amount * 14);\n const bits = Math.round(Math.pow(2, a - 1));\n\n let x = 0;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n curves[i] = Math.round(x * bits) / bits;\n }\n */\n\n break;\n case Distortion.OVERDRIVE:\n k = (2 * amount) / (1 - amount);\n\n for (let i = 0; i < numberOfSamples; i++) {\n // LINEAR INTERPOLATION: x := (c - a) * (z - y) / (b - a) + y\n // a = 0, b = 2048, z = 1, y = -1, c = i\n const x = (((i - 0) * (1 - (-1))) / (numberOfSamples - 0)) + (-1);\n curves[i] = ((1 + k) * x) / (1 + k * Math.abs(x));\n }\n\n /*\n let x = 0;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n\n if (x < -0.08905) {\n curves[i] = (-3 / 4) * (1 - (Math.pow((1 - (Math.abs(x) - 0.032857)), 12)) + (1 / 3) * (Math.abs(x) - 0.032847)) + 0.01;\n } else if (x >= -0.08905 && x < 0.320018) {\n curves[i] = (-6.153 * (x * x)) + 3.9375 * x;\n } else {\n curves[i] = 0.630035;\n }\n }\n */\n\n break;\n case Distortion.DISTORTION:\n a = 1 - amount;\n\n for (let i = 0; i < numberOfSamples; i++) {\n x = i * 2 / numberOfSamples - 1;\n y = x < 0 ? -Math.pow(Math.abs(x), a + 0.04) : Math.pow(x, a);\n curves[i] = (Math.exp(2 * y) - Math.exp(-2 * y)) / (Math.exp(2 * y) + Math.exp(-2 * y));\n }\n\n break;\n case Distortion.FUZZ:\n for (let i = 0; i < numberOfSamples; i++) {\n x = ((i * 2) / numberOfSamples) - 1;\n y = ((0.5 * Math.pow((x + 1.4), 2)) - 1) * y >= 0 ? 5.8 : 1.2;\n\n curves[i] = (Math.exp(y) - Math.exp(-y)) / (Math.exp(y) + Math.exp(-y));\n }\n\n break;\n case Distortion.CLEAN:\n default:\n return null;\n }\n\n return curves;\n }\n\n return null; // Clean sound (default value)\n }\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.distortion = context.createWaveShaper();\n this.drive = context.createGain();\n this.color = context.createBiquadFilter();\n this.tone = context.createBiquadFilter();\n\n // Distortion type\n this.type = Distortion.CLEAN;\n\n // for creating curve\n this.amount = 0.5;\n this.numberOfSamples = 4096;\n\n // Initialize parameters\n this.drive.gain.value = 1;\n this.color.type = (typeof this.color.type === 'string') ? 'bandpass' : (this.color.BANDPASS || 2);\n this.color.frequency.value = 350;\n this.color.Q.value = Math.SQRT1_2;\n this.color.gain.value = 0; // Not used\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n\n // `Distortion` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'curve':\n if (value === undefined) {\n return this.distortion.curve;\n }\n\n let curve = null;\n\n switch (String(value).toLowerCase()) {\n case Distortion.CLEAN:\n this.type = Distortion.CLEAN;\n curve = Distortion.createCurve(Distortion.CLEAN, this.amount, this.numberOfSamples);\n break;\n case Distortion.CRUNCH:\n this.type = Distortion.CRUNCH;\n curve = Distortion.createCurve(Distortion.CRUNCH, this.amount, this.numberOfSamples);\n break;\n case Distortion.OVERDRIVE:\n this.type = Distortion.OVERDRIVE;\n curve = Distortion.createCurve(Distortion.OVERDRIVE, this.amount, this.numberOfSamples);\n break;\n case Distortion.DISTORTION:\n this.type = Distortion.DISTORTION;\n curve = Distortion.createCurve(Distortion.DISTORTION, this.amount, this.numberOfSamples);\n break;\n case Distortion.FUZZ:\n this.type = Distortion.FUZZ;\n curve = Distortion.createCurve(Distortion.FUZZ, this.amount, this.numberOfSamples);\n break;\n default:\n if (value instanceof Float32Array) {\n curve = value;\n }\n\n break;\n }\n\n this.distortion.curve = curve;\n\n break;\n case 'amount':\n if (value === undefined) {\n return this.amount;\n }\n\n v = parseFloat(value);\n\n if ((v > 0) && (v < 1)) {\n this.amount = v;\n this.param('curve', this.type);\n }\n\n break;\n case 'samples':\n if (value === undefined) {\n return this.numberOfSamples;\n }\n\n v = parseInt(value, 10);\n\n if (v >= 0) {\n this.numberOfSamples = v;\n this.param('curve', this.type);\n }\n\n break;\n case 'drive':\n if (value === undefined) {\n return this.drive.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 100;\n\n if ((v >= min) && (v <= max)) {\n this.drive.gain.value = v;\n }\n\n break;\n case 'color':\n case 'tone' :\n if (value === undefined) {\n return this[k].frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this[k].frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.color.disconnect(0);\n this.drive.disconnect(0);\n this.distortion.disconnect(0);\n this.tone.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Color) -> WaveShaperNode (Distortion) -> GainNode (Drive) -> BiquadFilterNode (Tone) -> GainNode (Output)\n this.input.connect(this.color);\n this.color.connect(this.drive);\n this.drive.connect(this.distortion);\n this.distortion.connect(this.tone);\n this.tone.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'curve' : this.type,\n 'amount' : this.amount,\n 'samples' : this.numberOfSamples,\n 'drive' : this.drive.gain.value,\n 'color' : this.color.frequency.value,\n 'tone' : this.tone.frequency.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Distortion]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Envelope Generator.\n * @constructor\n */\nexport class EnvelopeGenerator {\n static MIN_GAIN = 1e-3;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n /** @type {Array.<GainNode>} */\n this.generators = [];\n\n // for `GainNode`\n this.activeIndexes = [];\n this.activeCounter = 0;\n\n this.attack = 0.01;\n this.decay = 0.3;\n this.sustain = 0.5;\n this.release = 1.0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|EnvelopeGenerator} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'attack' :\n case 'sustain':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this[k] = v;\n }\n\n break;\n case 'decay' :\n case 'release':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method connects the instance of `AudioNode`.\n * @param {number} index This argument is in order to select the instance of `GainNode` that is Envelope Generator.\n * @param {AudioNode} input This argument is the instance of `AudioNode` as input.\n * @param {AudioNode} output This argument is the instance of `AudioNode` as output.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n ready(index, input, output) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n if ((input instanceof AudioNode) && (output instanceof AudioNode)) {\n input.connect(this.generators[i]);\n this.generators[i].connect(output);\n } else if (input instanceof AudioNode) {\n input.connect(this.generators[i]);\n } else if (output instanceof AudioNode) {\n this.generators[i].connect(output);\n }\n\n this.activeIndexes[i] = i;\n this.activeCounter++;\n\n return this;\n }\n\n /**\n * This method changes gain (Attack -> Decay -> Sustain).\n * @param {number} startTime This argument is the start time of Attack.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n start(startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n // Attack -> Decay -> Sustain\n const t0 = s;\n const t1 = t0 + this.attack;\n const t2 = this.decay;\n const t2Value = this.sustain;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n // Start from `gain.value = 0`\n this.generators[activeIndex].gain.cancelScheduledValues(t0);\n this.generators[activeIndex].gain.setValueAtTime(0, t0);\n\n // Attack : `gain.value` increases linearly until assigned time (t1)\n this.generators[activeIndex].gain.linearRampToValueAtTime(1, t1);\n\n // Decay -> Sustain : `gain.value` gradually decreases to value of Sustain during of Decay time (t2) from assigned time (t1)\n this.generators[activeIndex].gain.setTargetAtTime(t2Value, t1, t2);\n }\n\n return this;\n }\n\n /**\n * This method changes gain (Attack or Decay or Sustain -> Release).\n * @param {number} stopTime This argument is the start time of Release.\n * @param {boolean} useCurve This argument is to use different methods.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n stop(stopTime, useCurve) {\n let s = parseFloat(stopTime) - this.release;\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n // Sustain -> Release\n const t3 = s;\n const t4 = this.release;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n // in the case of mouseup on the way of Decay\n this.generators[activeIndex].gain.cancelScheduledValues(t3);\n\n // Release : `gain.value` gradually decreases to 0 during of Release time (t4) from assigned time (t3)\n // NOTE: https://www.w3.org/TR/webaudio/#dom-audioparam-settargetattime\n if (useCurve) {\n this.generators[activeIndex].gain.setValueCurveAtTime(new Float32Array([1, 0.5, 0.25, 0]), t3, t4);\n } else {\n this.generators[activeIndex].gain.setTargetAtTime(0, t3, t4);\n }\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is the index of array that contains the instance of `GainNode` for Envelope Generator.\n * @return {GainNode} This is returned as the instance of `GainNode` for Envelope Generator.\n */\n getGenerator(index) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n return this.generators[i];\n }\n\n /**\n * This method sets the instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is the index of array that contains the instance of `GainNode` for Envelope Generator.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n setGenerator(index) {\n const i = (parseInt(index, 10) >= 0) ? parseInt(index, 10) : 0;\n\n this.generators[i] = this.context.createGain();\n\n // for legacy browsers\n this.generators[i].gain.setTargetAtTime = this.generators[i].gain.setTargetAtTime || this.generators[i].gain.setTargetValueAtTime;\n\n return this;\n }\n\n /**\n * This method determines whether the all of gain schedulings have ended.\n * @return {boolean} If the all of gain schedulings have ended, this value is `true`. Otherwise, this value is `false`.\n */\n isStop() {\n let counter = 0;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n if (this.generators[activeIndex].gain.value > EnvelopeGenerator.MIN_GAIN) {\n return false;\n }\n\n counter++;\n\n // the all of schedulings are stopped ?\n if (counter === this.activeCounter) {\n return true;\n }\n }\n }\n\n /**\n * This method clears variables for managing the instance of `GainNode`.\n * @param {boolean} isDisconnect This argument is in order to determine whether disconnect `AudioNode`.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n clear(isDisconnect) {\n this.activeIndexes.length = 0;\n this.activeCounter = 0;\n\n for (const generator of this.generators) {\n generator.gain.cancelScheduledValues(this.context.currentTime);\n generator.gain.value = 1;\n\n if (isDisconnect) {\n generator.disconnect(0);\n }\n }\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {\n 'attack' : this.attack,\n 'decay' : this.decay,\n 'sustain' : this.sustain,\n 'release' : this.release\n };\n\n return params;\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule EnvelopeGenerator]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Equalizer extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n **/\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n this.presence = context.createBiquadFilter();\n\n // Set filter type\n this.bass.type = (typeof this.bass.type === 'string') ? 'lowshelf' : (this.bass.LOWSHELF || 3);\n this.middle.type = (typeof this.middle.type === 'string') ? 'peaking' : (this.middle.PEAKING || 5);\n this.treble.type = (typeof this.treble.type === 'string') ? 'peaking' : (this.treble.PEAKING || 5);\n this.presence.type = (typeof this.presence.type === 'string') ? 'highshelf' : (this.presence.HIGHSHELF || 4);\n\n // Set cutoff frequency\n this.bass.frequency.value = 500; // 500 Hz\n this.middle.frequency.value = 1000; // 1 kHz\n this.treble.frequency.value = 2000; // 2 kHz\n this.presence.frequency.value = 4000; // 4 kHz\n\n // Set Q\n // this.bass.Q.value = Math.SQRT1_2; // Not used\n this.middle.Q.value = Math.SQRT1_2;\n this.treble.Q.value = Math.SQRT1_2;\n // this.presence.Q.value = Math.SQRT1_2; // Not used\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n this.presence.gain.value = 0;\n\n // `Equalizer` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'bass' :\n case 'middle' :\n case 'treble' :\n case 'presence':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = -40;\n max = 40;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.bass.disconnect(0);\n this.middle.disconnect(0);\n this.treble.disconnect(0);\n this.presence.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Bass) -> BiquadFilterNode (Middle) -> BiquadFilterNode (Treble) -> BiquadFilterNode (Presence) -> GainNode (Output)\n this.input.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.connect(this.presence);\n this.presence.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'bass' : this.bass.gain.value,\n 'middle' : this.middle.gain.value,\n 'treble' : this.treble.gain.value,\n 'presence' : this.presence.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Equalizer]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Filter extends Effector {\n // for legacy browsers\n static FILTER_TYPES = {\n 'lowpass' : 0,\n 'highpass' : 1,\n 'bandpass' : 2,\n 'lowshelf' : 3,\n 'highshelf' : 4,\n 'peaking' : 5,\n 'notch' : 6,\n 'allpass' : 7\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.filter = context.createBiquadFilter();\n\n // for legacy browsers\n this.filter.frequency.setTargetAtTime = this.filter.frequency.setTargetAtTime || this.filter.frequency.setTargetValueAtTime;\n\n // Initialize parameters\n this.filter.type = (typeof this.filter.type === 'string') ? 'lowpass' : (this.filter.LOWPASS || 0);\n this.filter.frequency.value = 350;\n this.filter.Q.value = 1;\n this.filter.gain.value = 0;\n\n this.maxFrequency = this.filter.frequency.value;\n this.range = 0.1; // 10% -> between `this.maxFrequency * 0.1` and `this.maxFrequency`\n\n this.attack = 0.01;\n this.decay = 0.3;\n this.sustain = 1.0;\n this.release = 1.0;\n\n // `Filter` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.filter.type;\n }\n\n v = String(value).toLowerCase();\n\n if (v in Filter.FILTER_TYPES) {\n this.filter.type = (typeof this.filter.type === 'string') ? v : Filter.FILTER_TYPES[v];\n }\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.filter.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.maxFrequency = v;\n this.filter.frequency.value = v;\n }\n\n break;\n case 'gain':\n if (value === undefined) {\n return this.filter.gain.value;\n }\n\n v = parseFloat(value);\n min = -40;\n max = 40;\n\n if ((v >= min) && (v <= max)) {\n this.filter.gain.value = v;\n }\n\n break;\n case 'q':\n if (value === undefined) {\n return this.filter.Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n this.filter.Q.value = v;\n }\n\n break;\n case 'range':\n if (value === undefined) {\n return this.range;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.range = v;\n }\n\n break;\n case 'attack' :\n case 'sustain':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this[k] = v;\n }\n\n break;\n case 'decay' :\n case 'release':\n if (value === undefined) {\n return this[k];\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this[k] = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.filter.disconnect(0);\n\n if (this.isActive) {\n // Effector ON\n\n // GainNode (Input) -> BiquadFilterNode -> GainNode (Output)\n this.input.connect(this.filter);\n this.filter.connect(this.output);\n } else {\n // Effector OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start(startTime) {\n if (this.isActive) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t0 = s;\n const t1 = t0 + this.attack;\n const t2 = this.decay;\n const t2Value = this.sustain * this.maxFrequency;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n this.filter.frequency.cancelScheduledValues(t0);\n this.filter.frequency.setValueAtTime(minFrequnecy, t0);\n this.filter.frequency.linearRampToValueAtTime(this.maxFrequency, t1); // Attack\n this.filter.frequency.setTargetAtTime(t2Value, t1, t2); // Decay -> Sustain\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime) {\n if (this.isActive) {\n let s = parseFloat(stopTime) - this.release;\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t3 = s;\n const t4 = this.release;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n this.filter.frequency.cancelScheduledValues(t3);\n this.filter.frequency.setValueAtTime(this.filter.frequency.value, t3);\n this.filter.frequency.setTargetAtTime(minFrequnecy, t3, t4); // Sustain -> Release\n }\n\n return this;\n }\n\n /** @override */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'type' : this.filter.type,\n 'frequency' : this.filter.frequency.value,\n 'Q' : this.filter.Q.value,\n 'gain' : this.filter.gain.value,\n 'range' : this.range,\n 'attack' : this.attack,\n 'decay' : this.decay,\n 'sustain' : this.sustain,\n 'release' : this.release\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Filter]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Flanger extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.delay = context.createDelay();\n this.mix = context.createGain();\n this.tone = context.createBiquadFilter();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Flanger` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (delayTime)\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delay.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.delay.delayTime.value = v;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.delay.delayTime.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.mix.disconnect(0);\n this.tone.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive) {\n // GainNode (Input) -> BiquadFilterNode (Tone) -> DelayNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.delay);\n this.delay.connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> DelayNode -> GainNode (Feedback) -> DelayNode ...\n this.delay.connect(this.feedback);\n this.feedback.connect(this.delay);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delay.delayTime.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'tone' : this.tone.frequency.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Flanger]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Listener extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n // the instance of `AudioListener`\n this.listener = context.listener;\n\n // Set default value\n this.positions = { 'x' : 0, 'y' : 0, 'z' : 0 };\n this.forwards = { 'x' : 0, 'y' : 0, 'z' : -1 };\n this.ups = { 'x' : 0, 'y' : 1, 'z' : 0 };\n\n if ((this.listener.positionX instanceof AudioParam) && (this.listener.positionY instanceof AudioParam) && (this.listener.positionZ instanceof AudioParam)) {\n this.listener.positionX.setValueAtTime(this.positions.x, context.currentTime);\n this.listener.positionY.setValueAtTime(this.positions.y, context.currentTime);\n this.listener.positionZ.setValueAtTime(this.positions.z, context.currentTime);\n } else {\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Listener} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'x':\n case 'y':\n case 'z':\n if (value === undefined) {\n return this.positions[k];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.positions[k] = v;\n\n if ((this.listener.positionX instanceof AudioParam) && (this.listener.positionY instanceof AudioParam) && (this.listener.positionZ instanceof AudioParam)) {\n this.listener.positionX.setValueAtTime(this.positions.x, this.context.currentTime);\n this.listener.positionY.setValueAtTime(this.positions.y, this.context.currentTime);\n this.listener.positionZ.setValueAtTime(this.positions.z, this.context.currentTime);\n } else {\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n }\n\n break;\n case 'fx':\n case 'fy':\n case 'fz':\n if (value === undefined) {\n return this.forwards[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.forwards[k.charAt(1)] = v;\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, this.context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, this.context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, this.context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, this.context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n break;\n case 'ux':\n case 'uy':\n case 'uz':\n if (value === undefined) {\n return this.ups[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.ups[k.charAt(1)] = v;\n\n if ((this.listener.forwardX instanceof AudioParam) &&\n (this.listener.forwardY instanceof AudioParam) &&\n (this.listener.forwardZ instanceof AudioParam) &&\n (this.listener.upX instanceof AudioParam) &&\n (this.listener.upY instanceof AudioParam) &&\n (this.listener.upZ instanceof AudioParam)) {\n this.listener.forwardX.setValueAtTime(this.forwards.x, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(this.forwards.y, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(this.forwards.z, this.context.currentTime);\n this.listener.upX.setValueAtTime(this.ups.x, this.context.currentTime);\n this.listener.upY.setValueAtTime(this.ups.y, this.context.currentTime);\n this.listener.upZ.setValueAtTime(this.ups.z, this.context.currentTime);\n } else {\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets effecter's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {\n 'state' : this.isActive,\n 'positions' : this.positions,\n 'forwards' : this.forwards,\n 'ups' : this.ups\n };\n\n return params;\n }\n\n /**\n * This method gets effecter's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule Listener]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Panner extends Effector {\n static PANNING_MODELS = {\n 'equalpower' : 0,\n 'HRTF' : 1\n };\n\n static DISTANCE_MODELS = {\n 'linear' : 0,\n 'inverse' : 1,\n 'exponential' : 2\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.panner = context.createPanner();\n\n this.positions = { 'x' : 0, 'y' : 0, 'z' : 0 };\n this.orientations = { 'x' : 1, 'y' : 0, 'z' : 0 };\n\n this.panner.refDistance = 1;\n this.panner.maxDistance = 10000;\n this.panner.rolloffFactor = 1;\n\n this.panner.coneInnerAngle = 360;\n this.panner.coneOuterAngle = 360;\n this.panner.coneOuterGain = 0;\n\n this.panner.panningModel = (typeof this.panner.panningModel === 'string') ? 'HRTF' : (this.panner.HRTF || 1);\n this.panner.distanceModel = (typeof this.panner.distanceModel === 'string') ? 'inverse' : (this.panner.INVERSE_DISTANCE || 1);\n\n if ((this.panner.positionX instanceof AudioParam) && (this.panner.positionY instanceof AudioParam) && (this.panner.positionZ instanceof AudioParam)) {\n this.panner.positionX.setValueAtTime(this.positions.x, context.currentTime);\n this.panner.positionY.setValueAtTime(this.positions.y, context.currentTime);\n this.panner.positionZ.setValueAtTime(this.positions.z, context.currentTime);\n } else {\n this.panner.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n if ((this.panner.orientationX instanceof AudioParam) && (this.panner.orientationY instanceof AudioParam) && (this.panner.orientationZ instanceof AudioParam)) {\n this.panner.orientationX.setValueAtTime(this.orientations.x, context.currentTime);\n this.panner.orientationY.setValueAtTime(this.orientations.y, context.currentTime);\n this.panner.orientationZ.setValueAtTime(this.orientations.z, context.currentTime);\n } else {\n this.panner.setOrientation(this.orientations.x, this.orientations.y, this.orientations.z);\n }\n\n // `Panner` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'x':\n case 'y':\n case 'z':\n if (value === undefined) {\n return this.positions[k];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.positions[k] = v;\n\n if ((this.panner.positionX instanceof AudioParam) && (this.panner.positionY instanceof AudioParam) && (this.panner.positionZ instanceof AudioParam)) {\n this.panner.positionX.setValueAtTime(this.positions.x, this.context.currentTime);\n this.panner.positionY.setValueAtTime(this.positions.y, this.context.currentTime);\n this.panner.positionZ.setValueAtTime(this.positions.z, this.context.currentTime);\n } else {\n this.panner.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n }\n\n break;\n case 'ox':\n case 'oy':\n case 'oz':\n if (value === undefined) {\n return this.orientations[k.charAt(1)];\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.orientations[k.charAt(1)] = v;\n\n if ((this.panner.orientationX instanceof AudioParam) && (this.panner.orientationY instanceof AudioParam) && (this.panner.orientationZ instanceof AudioParam)) {\n this.panner.orientationX.setValueAtTime(this.orientations.x, this.context.currentTime);\n this.panner.orientationY.setValueAtTime(this.orientations.y, this.context.currentTime);\n this.panner.orientationZ.setValueAtTime(this.orientations.z, this.context.currentTime);\n } else {\n this.panner.setOrientation(this.orientations.x, this.orientations.y, this.orientations.z);\n }\n }\n\n break;\n case 'refdistance':\n if (value === undefined) {\n return this.panner.refDistance;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.panner.refDistance = v;\n }\n\n break;\n case 'maxdistance':\n if (value === undefined) {\n return this.panner.maxDistance;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.panner.maxDistance = v;\n }\n\n break;\n case 'rollofffactor':\n if (value === undefined) {\n return this.panner.rolloffFactor;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.panner.rolloffFactor = v;\n }\n\n break;\n case 'coneinnerangle':\n if (value === undefined) {\n return this.panner.coneInnerAngle;\n }\n\n v = parseFloat(value);\n\n if ((v >= 0) && (v <= 360)) {\n this.panner.coneInnerAngle = v;\n }\n\n break;\n case 'coneouterangle':\n if (value === undefined) {\n return this.panner.coneOuterAngle;\n }\n\n v = parseFloat(value);\n\n if ((v >= 0) && (v <= 360)) {\n this.panner.coneOuterAngle = v;\n }\n\n break;\n case 'coneoutergain':\n if ((v >= 0) && (v <= 1)) {\n return this.panner.coneOuterGain;\n }\n\n v = parseFloat(value);\n\n if (!isNaN(v)) {\n this.panner.coneOuterGain = v;\n }\n\n break;\n case 'panningmodel':\n if (value === undefined) {\n return this.panner.panningModel;\n }\n\n v = /HRTF/i.test(value) ? String(value).toUpperCase() : String(value).toLowerCase();\n\n if (v in Panner.PANNING_MODELS) {\n this.panner.panningModel = (typeof this.panner.panningModel === 'string') ? v : Panner.PANNING_MODELS[v];\n }\n\n break;\n case 'distancemodel':\n if (value === undefined) {\n return this.panner.distanceModel;\n }\n\n v = String(value).replace(/-/g, '').toLowerCase();\n\n if (v in Panner.DISTANCE_MODELS) {\n this.panner.distanceModel = (typeof this.panner.distanceModel === 'string') ? v : Panner.DISTANCE_MODELS[v];\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.panner.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> PannerNode -> GainNode (Output)\n this.input.connect(this.panner);\n this.panner.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'positions' : this.positions,\n 'orientations' : this.orientations,\n 'refDistance' : this.panner.refDistance,\n 'maxDistance' : this.panner.maxDistance,\n 'rolloffFactor' : this.panner.rolloffFactor,\n 'coneInnerAngle' : this.panner.coneInnerAngle,\n 'coneOuterAngle' : this.panner.coneOuterAngle,\n 'coneOuterGain' : this.panner.coneOuterGain,\n 'panningModel' : this.panner.panningModel,\n 'distanceModel' : this.panner.distanceModel\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Panner]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Phaser extends Effector {\n static MAXIMUM_STAGES = 24; // The maximum number of All-Pass Filters\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.numberOfStages = 12; // The default number of All-Pass Filters\n this.filters = new Array(Phaser.MAXIMUM_STAGES);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i] = context.createBiquadFilter();\n this.filters[i].type = (typeof this.filters[i].type === 'string') ? 'allpass' : (this.filters[i].ALLPASS || 7);\n this.filters[i].frequency.value = 350;\n this.filters[i].Q.value = 1;\n this.filters[i].gain.value = 0; // Not used\n }\n\n this.mix = context.createGain();\n this.feedback = context.createGain();\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.mix.gain.value = 0;\n this.feedback.gain.value = 0;\n this.depthRate = 0;\n\n // `Phaser` is not connected by default\n this.state(false);\n\n // LFO\n // GainNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'stage':\n if (value === undefined) {\n return this.numberOfStages;\n }\n\n v = parseInt(value, 10);\n\n switch (v) {\n case 0:\n case 2:\n case 4:\n case 8:\n case 12:\n case 24:\n this.numberOfStages = v;\n this.connect();\n break;\n default:\n break;\n }\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.filters[0].frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i].frequency.value = v;\n }\n\n this.depth.gain.value = this.filters[0].frequency.value * this.depthRate;\n }\n\n break;\n case 'resonance':\n if (value === undefined) {\n return this.filters[0].Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[0].Q.value = v;\n }\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.filters[0].frequency.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'mix' :\n case 'feedback':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.filters[i].disconnect(0);\n }\n\n this.mix.disconnect(0);\n this.feedback.disconnect(0);\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n\n // Effect ON\n if (this.isActive && (this.numberOfStages > 0)) {\n // GainNode (Input) -> BiquadFilterNode (All-Pass Filter x N) -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.filters[0]);\n\n for (let i = 0; i < this.numberOfStages; i++) {\n if (i < (this.numberOfStages - 1)) {\n this.filters[i].connect(this.filters[i + 1]);\n } else {\n this.filters[i].connect(this.mix);\n this.mix.connect(this.output);\n\n // Feedback\n // GainNode (Input) -> BiquadFilterNode (All-Pass Filter x N) -> GainNode (Feedback) -> BiquadFilterNode (All-Pass Filter x N) ...\n this.filters[i].connect(this.feedback);\n this.feedback.connect(this.filters[0]);\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAXIMUM_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'stage' : this.numberOfStages,\n 'frequency' : this.filters[0].frequency.value,\n 'resonance' : this.filters[0].Q.value,\n 'depth' : this.depthRate,\n 'rate' : this.rate.value,\n 'mix' : this.mix.gain.value,\n 'feedback' : this.feedback.gain.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Phaser]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class PitchShifter extends Effector {\n /**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\n static FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n }\n\n /**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\n static IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n }\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.pitch = 1;\n\n // `PitchShifter` is not connected by default\n this.state(false);\n\n this.connect();\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n\n switch (k) {\n case 'pitch':\n if (value === undefined) {\n return this.pitch;\n }\n\n v = parseFloat(value);\n min = 0;\n\n if (v > min) {\n this.pitch = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> ScriptProcessorNode -> GainNode (Output);\n this.input.connect(this.processor);\n this.processor.connect(this.output);\n } else {\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start() {\n if (this.isActive && this.isStop) {\n this.isStop = false;\n\n const bufferSize = this.processor.bufferSize;\n\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.pitch !== 1)) {\n const realLs = new Float32Array(inputLs);\n const realRs = new Float32Array(inputRs);\n const imagLs = new Float32Array(bufferSize);\n const imagRs = new Float32Array(bufferSize);\n\n PitchShifter.FFT(realLs, imagLs, bufferSize);\n PitchShifter.FFT(realRs, imagRs, bufferSize);\n\n const arealLs = new Float32Array(bufferSize);\n const arealRs = new Float32Array(bufferSize);\n const aimagLs = new Float32Array(bufferSize);\n const aimagRs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n const offset = Math.floor(this.pitch * i);\n\n let eq = 1;\n\n if (i > (bufferSize / 2)) {\n eq = 0;\n }\n\n if ((offset >= 0) && (offset < bufferSize)) {\n arealLs[offset] += eq * realLs[i];\n aimagLs[offset] += eq * imagLs[i];\n arealRs[offset] += eq * realRs[i];\n aimagRs[offset] += eq * imagRs[i];\n }\n }\n\n PitchShifter.IFFT(arealLs, aimagLs, bufferSize);\n PitchShifter.IFFT(arealRs, aimagRs, bufferSize);\n\n outputLs.set(arealLs);\n outputRs.set(arealRs);\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop() {\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // Connect nodes again\n this.connect();\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'pitch' : this.pitch\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule PitchShifter]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Reverb extends Effector {\n static ERROR_AJAX = 'error';\n static ERROR_AJAX_TIMEOUT = 'timeout';\n static ERROR_DECODE = 'decode';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n // If the error is at least 1, this method aborts the all of connections.\n // Therefore, this flag are shared with the all instances of `XMLHttpRequest`.\n this.isLoadError = false;\n\n this.rirs = [];\n this.convolver = context.createConvolver();\n this.dry = context.createGain();\n this.wet = context.createGain();\n this.tone = context.createBiquadFilter();\n\n // Initialize parameters\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = (typeof this.tone.type === 'string') ? 'lowpass' : (this.tone.LOWPASS || 0);\n this.tone.frequency.value = 350;\n this.tone.Q.value = Math.SQRT1_2;\n this.tone.gain.value = 0; // Not used\n\n // `Reverb` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.convolver.buffer;\n }\n\n v = parseInt(value, 10);\n min = 0;\n max = this.rirs.length - 1;\n\n if (value === null) {\n this.convolver.buffer = null;\n\n // If `buffer` in `ConvolverNode` is `null` after setting the instance of `AudioBuffer`, `Reverb` is not OFF.\n // Therefore, `Reverb` is OFF by disconnecting nodes.\n this.input.disconnect(0);\n this.input.connect(this.output);\n } else if ((v >= min) && (v <= max)) {\n this.convolver.buffer = this.rirs[v];\n this.connect();\n }\n\n break;\n case 'dry':\n case 'wet':\n if (value === undefined) {\n return this[k].gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this[k].gain.value = v;\n }\n\n break;\n case 'tone':\n if (value === undefined) {\n return this.tone.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.tone.frequency.value = v;\n }\n\n break;\n case 'rirs':\n return this.rirs; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.convolver.disconnect(0);\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n this.tone.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Dry) -> GainNode (Output)\n this.input.connect(this.dry);\n this.dry.connect(this.output);\n\n // GainNode (Input) -> BiquadFilterNode (Tone) -> ConvolverNode -> GainNode (Mix) -> GainNode (Output)\n this.input.connect(this.tone);\n this.tone.connect(this.convolver);\n this.convolver.connect(this.wet);\n this.wet.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /**\n * This method sets instance of `AudioBuffer` to `ConvolverNode`.\n * @param {AudioBuffer|ArrayBuffer} impulse This argument is in order to convolve impulse response.\n * This argument is the instance of `AudioBuffer` or `ArrayBuffer` for impulse response.\n * @param {function} errorCallback This argument is in order to be invoked when error occurs.\n * @return {Reverb} This is returned for method chain.\n * @override\n */\n start(impulse, errorCallback) {\n if ((impulse instanceof AudioBuffer) || (impulse === null)) {\n this.convolver.buffer = impulse;\n this.rirs.push(impulse); // Add to preset\n } else if (impulse instanceof ArrayBuffer) {\n const successCallback = buffer => {\n this.convolver.buffer = buffer;\n this.rirs.push(buffer); // Add to preset\n };\n\n if (Object.prototype.toString.call(errorCallback) !== '[object Function]') {\n errorCallback = () => {};\n }\n\n this.context.decodeAudioData(impulse, successCallback, errorCallback);\n }\n\n return this;\n }\n\n /**\n * This method creates the instances of `AudioBuffer` by Ajax for Revreb presets.\n * @param {Array.<string>|Array.<AudioBuffer>} rirs This argument is either URLs or the instances of `AudioBuffer` for impulse response.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked when the creating the instances of `AudioBuffer` was completed.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {Reverb} This is returned for method chain.\n */\n preset(rirs, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('rirs' in properties) {\n rirs = properties.rirs;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!Array.isArray(rirs)) {\n rirs = [rirs];\n }\n\n this.rirs = new Array(rirs.length);\n\n const t = parseInt(timeout, 10);\n\n for (let i = 0, len = rirs.length; i < len; i++) {\n if (typeof rirs[i] === 'string') {\n // Get the instances of `AudioBuffer` from the designated URLs.\n this.load(rirs[i], i, t, successCallback, errorCallback, progressCallback);\n } else if (rirs[i] instanceof AudioBuffer) {\n // Get the instances of `AudioBuffer` directly\n this.rirs[i] = rirs[i];\n }\n }\n\n return this;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates the instances of `AudioBuffer`.\n * @param {string} url This argument is resource URL for one-shot audio.\n * @param {number} index This argument is in order to assign the instance of `AudioBuffer`.\n * @param {number} timeout This argument is Ajax timeout.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {Reverb} This is returned for method chain.\n */\n load(url, index, timeout, successCallback, errorCallback, progressCallback) {\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = (timeout > 0) ? timeout : 60000;\n\n xhr.ontimeout = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, Reverb.ERROR_AJAX_TIMEOUT);\n }\n\n this.isLoadError = true;\n };\n\n xhr.onprogress = event => {\n if (this.isLoadError) {\n xhr.abort();\n } else if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, Reverb.ERROR_AJAX);\n }\n\n this.isLoadError = true;\n };\n\n // Success\n xhr.onload = event => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = audioBuffer => {\n this.rirs[index] = audioBuffer;\n\n // The creating the instances of `AudioBuffer` has completed ?\n for (const rir of this.rirs) {\n if (rir === undefined) {\n return;\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(event);\n }\n };\n\n const decodeErrorCallback = error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error, Reverb.ERROR_DECODE);\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n\n return this;\n }\n\n /** @override */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n // Change connection\n this.connect();\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'dry' : this.dry.gain.value,\n 'wet' : this.wet.gain.value,\n 'tone' : this.tone.frequency.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Reverb]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Ringmodulator extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitude = context.createGain();\n\n this.amplitude.gain.value = 0; // 0 +- depth\n\n // Initialize parameter\n this.depth.gain.value = 1;\n this.rate.value = 0;\n\n // `Ringmodulator` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (gain)\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitude.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode -> GainNode (Output)\n this.input.connect(this.amplitude);\n this.amplitude.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Ringmodulator]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Stereo extends Effector {\n static MAX_DELAY_TIME = 1; // Max delay time is 1000 [ms]\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createScriptProcessor(bufferSize, 2, 2);\n this.delayL = context.createDelay(Stereo.MAX_DELAY_TIME);\n this.delayR = context.createDelay(Stereo.MAX_DELAY_TIME);\n\n // Initialize parameters\n this.delayL.delayTime.value = 0;\n this.delayR.delayTime.value = 0;\n\n // `Stereo` is not connected by default\n this.state(false);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'delaytime':\n case 'time' :\n if (value === undefined) {\n return this.delayL.delayTime.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = Stereo.MAX_DELAY_TIME;\n\n if ((v >= min) && (v <= max)) {\n this.delayL.delayTime.value = v;\n this.delayR.delayTime.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.splitter.disconnect(0);\n this.delayL.disconnect(0);\n this.delayR.disconnect(0);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> ChannelSplitterNode -> DelayNode (L) / (R) -> ScriptProcessorNode -> GainNode (Output)\n this.input.connect(this.splitter);\n this.splitter.connect(this.delayL, 0, 0);\n this.splitter.connect(this.delayR, 1, 0);\n this.delayL.connect(this.merger);\n this.delayR.connect(this.merger);\n this.merger.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n start() {\n if (this.isActive && this.isStop) {\n this.isStop = false;\n\n const bufferSize = this.merger.bufferSize;\n\n this.merger.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.isActive && (this.delayL.delayTime.value !== 0) && (this.delayR.delayTime.value !== 0)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = inputLs[i];\n outputRs[i] = -inputRs[i];\n }\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /** @override */\n stop() {\n // Effector's state is active ?\n if (this.isActive) {\n // Stop `onaudioprocess` event\n this.merger.disconnect(0);\n this.merger.onaudioprocess = null;\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'time' : this.delayL.delayTime.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Stereo]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Tremolo extends Effector {\n // for legacy browsers\n static WAVE_TYPES = {\n 'sine' : 0,\n 'square' : 1,\n 'sawtooth' : 2,\n 'triangle' : 3\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.amplitude = context.createGain();\n\n this.amplitude.gain.value = 1; // 1 +- depth\n\n // Initialize parameter\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Tremolo` is not connected by default\n this.state(false);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (gain)\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'wave':\n if (value === undefined) {\n return this.lfo.type;\n }\n\n v = String(value).toLowerCase();\n\n if (v in Tremolo.WAVE_TYPES) {\n this.lfo.type = (typeof this.lfo.type === 'string') ? v : Tremolo.WAVE_TYPES[v];\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.amplitude.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode -> GainNode (Output)\n this.input.connect(this.amplitude);\n this.amplitude.connect(this.output);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'depth' : this.depth.gain.value,\n 'rate' : this.rate.value,\n 'wave' : this.lfo.type\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Tremolo]';\n }\n}\n","'use strict';\n\nimport { Effector } from './Effector';\n\n/**\n * Effector's subclass\n * @constructor\n * @extends {Effector}\n */\nexport class Wah extends Effector {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.autoWah = false;\n\n this.lowpass = context.createBiquadFilter();\n this.envelopeFollower = context.createWaveShaper();\n this.sensitivity = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = (typeof this.lowpass.type === 'string') ? 'lowpass' : (this.lowpass.LOWPASS || 0);\n this.lowpass.frequency.value = this.autoWah ? 20 : 350;\n this.lowpass.Q.value = 1;\n this.lowpass.gain.value = 0; // Not used\n\n this.envelopeFollower.curve = new Float32Array([1, 0, 1]);\n\n this.sensitivity.type = (typeof this.lowpass.type === 'string') ? 'lowpass' : (this.lowpass.LOWPASS || 0);\n this.sensitivity.frequency.value = 350;\n this.sensitivity.Q.value = 1;\n this.sensitivity.gain.value = 0; // Not used\n\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.depthRate = 0;\n\n // `Wah` is not connected by default\n this.state(false);\n this.connect();\n }\n\n /** @override */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'auto':\n if (value === undefined) {\n return this.autoWah;\n }\n\n this.autoWah = Boolean(value);\n this.connect();\n\n break;\n case 'frequency':\n case 'cutoff' :\n if (value === undefined) {\n return this.autoWah ? this.sensitivity.frequency.value : this.lowpass.frequency.value;\n }\n\n v = parseFloat(value);\n min = 10;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n if (this.autoWah) {\n this.sensitivity.frequency.value = v;\n this.lowpass.frequency.value = 20;\n } else {\n this.lowpass.frequency.value = v;\n }\n }\n\n break;\n case 'depth':\n if (value === undefined) {\n return this.depthRate;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth.gain.value = this.autoWah ? 10000 * v : this.lowpass.frequency.value * v;\n this.depthRate = v;\n }\n\n break;\n case 'rate':\n if (value === undefined) {\n return this.rate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = this.context.sampleRate / 2;\n\n if ((v >= min) && (v <= max)) {\n this.rate.value = v;\n }\n\n break;\n case 'resonance':\n if (value === undefined) {\n return this.autoWah ? this.sensitivity.Q.value : this.lowpass.Q.value;\n }\n\n v = parseFloat(value);\n min = 0.0001;\n max = 1000;\n\n if ((v >= min) && (v <= max)) {\n if (this.autoWah) {\n this.sensitivity.Q.value = v;\n this.lowpass.Q.value = 1;\n } else {\n this.lowpass.Q.value = v;\n }\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n stop(stopTime, releaseTime) {\n super.stop(stopTime, releaseTime);\n\n if (!this.autoWah && this.isActive) {\n // Connect nodes again\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n\n return this;\n }\n\n /** @override */\n connect() {\n // Clear connection\n this.input.disconnect(0);\n this.sensitivity.disconnect(0);\n this.envelopeFollower.disconnect(0);\n this.lowpass.disconnect(0);\n this.depth.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n if (this.autoWah) {\n // GainNode (Input) -> BiquadFilterNode (Sensitivity) -> GainNode (Output)\n this.input.connect(this.sensitivity);\n this.sensitivity.connect(this.output);\n\n // WaveShaperNode (Envelope Follower) -> BiquadFilterNode (Low-Pass Filter) -> GainNode (Depth) -> AudioParam (frequency)\n this.input.connect(this.envelopeFollower);\n this.envelopeFollower.connect(this.lowpass);\n this.lowpass.connect(this.depth);\n this.depth.connect(this.sensitivity.frequency);\n } else {\n // GainNode (Input) -> BiquadFilterNode (Low-Pass Filter) -> GainNode (Output)\n this.input.connect(this.lowpass);\n this.lowpass.connect(this.output);\n\n // LFO\n // OscillatorNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this;\n }\n\n /** @override */\n params() {\n const params = {\n 'state' : this.isActive,\n 'auto' : this.autoWah,\n 'cutoff' : this.autoWah ? this.sensitivity.frequency.value : this.lowpass.frequency.value,\n 'depth' : this.autoWah ? this.depth.gain.value : this.depthRate,\n 'rate' : this.rate.value,\n 'resonance' : this.autoWah ? this.sensitivity.Q.value : this.lowpass.Q.value\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[SoundModule Wah]';\n }\n}\n","'use strict';\n\nimport { Analyser } from './Analyser';\nimport { Recorder } from './Recorder';\nimport { Session } from './Session';\nimport { Effector } from './Effectors/Effector';\nimport { Autopanner } from './Effectors/Autopanner';\nimport { AutopannerFallback } from './Effectors/AutopannerFallback';\nimport { Chorus } from './Effectors/Chorus';\nimport { Compressor } from './Effectors/Compressor';\nimport { Delay } from './Effectors/Delay';\nimport { Distortion } from './Effectors/Distortion';\nimport { EnvelopeGenerator } from './Effectors/EnvelopeGenerator';\nimport { Equalizer } from './Effectors/Equalizer';\nimport { Filter } from './Effectors/Filter';\nimport { Flanger } from './Effectors/Flanger';\nimport { Listener } from './Effectors/Listener';\nimport { Panner } from './Effectors/Panner';\nimport { Phaser } from './Effectors/Phaser';\nimport { PitchShifter } from './Effectors/PitchShifter';\nimport { Reverb } from './Effectors/Reverb';\nimport { Ringmodulator } from './Effectors/Ringmodulator';\nimport { Stereo } from './Effectors/Stereo';\nimport { Tremolo } from './Effectors/Tremolo';\nimport { Wah } from './Effectors/Wah';\n\n/**\n * This class is superclass that is the top in this library.\n * This library's users do not create the instance of `SoundModule`.\n * This class is used for inherit in subclass (`OscillatorModule`, `OneshotModule`, `AudioModule`, `MediaModule`, `StreamModule`, `MixerModule`, `ProcessorModule`).\n * Therefore, this class defines the common properties for each sound sources.\n * @constructor\n */\nexport class SoundModule {\n static NUMBER_OF_INPUTS = 2;\n static NUMBER_OF_OUTPUTS = 2;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n this.init(context, bufferSize);\n }\n\n /**\n * This method initials modules.\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * However, the opportunity for designating buffer size is not so much.\n * The reason why is that the constructor of `SoundModule` selects buffer size automaticly.\n * This buffer size can be changed explicitly by calling `resize` method.\n */\n init(context, bufferSize) {\n if (Array.isArray(this.modules) && (this.modules.length > 0)) {\n this.mastervolume.disconnect(0);\n this.mastervolume = null;\n\n this.processor.disconnect(0);\n this.processor = null;\n\n this.analyser.INPUT.disconnect(0);\n this.analyser = null;\n\n this.recorder.INPUT.disconnect(0);\n this.recorder = null;\n\n this.session.INPUT.disconnect(0);\n this.session = null;\n\n this.modules.forEach(module => {\n module.INPUT.disconnect(0);\n module.OUTPUT.disconnect(0);\n module = null;\n });\n\n this.modules = [];\n }\n\n this.context = context;\n this.sampleRate = context.sampleRate;\n\n let size = parseInt(bufferSize, 10);\n\n switch (size) {\n case 256:\n case 512:\n case 1024:\n case 2048:\n case 4096:\n case 8192:\n case 16384:\n break;\n default:\n size = 0;\n break;\n }\n\n this.mastervolume = context.createGain();\n this.processor = context.createScriptProcessor(size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context, size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n this.session = new Session(context, size, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS, this.analyser);\n this.stereo = new Stereo(context, size);\n this.compressor = new Compressor(context, size);\n this.distortion = new Distortion(context, size);\n this.wah = new Wah(context, size);\n this.pitchshifter = new PitchShifter(context, size);\n this.equalizer = new Equalizer(context, size);\n this.filter = new Filter(context, size);\n this.autopanner = context.createStereoPanner ? new Autopanner(context, size) : new AutopannerFallback(context, size);\n this.tremolo = new Tremolo(context, size);\n this.ringmodulator = new Ringmodulator(context, size);\n this.phaser = new Phaser(context, size);\n this.flanger = new Flanger(context, size);\n this.chorus = new Chorus(context, size);\n this.delay = new Delay(context, size);\n this.reverb = new Reverb(context, size);\n this.panner = new Panner(context, size);\n this.listener = new Listener(context, size);\n this.envelopegenerator = new EnvelopeGenerator(context);\n\n // The default order for connection\n this.modules = [\n this.stereo,\n this.compressor,\n this.distortion,\n this.wah,\n this.pitchshifter,\n this.equalizer,\n this.filter,\n this.autopanner,\n this.tremolo,\n this.ringmodulator,\n this.phaser,\n this.flanger,\n this.chorus,\n this.delay,\n this.reverb,\n this.panner\n ];\n }\n\n /** @abstract */\n setup() {\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string} key This argument is property name.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number} This is returned as the value of designated property in the case of getter.\n */\n param(key, value) {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'mastervolume':\n if (value === undefined) {\n return this.mastervolume.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.mastervolume.gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n /** @abstract */\n ready() {\n return this;\n }\n\n /** @abstract */\n start() {\n return this;\n }\n\n /** @abstract */\n stop() {\n return this;\n }\n\n /** @abstract */\n get() {\n return this;\n }\n\n /**\n * This method changes buffer size for `ScriptProcessorNode`.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * This value is one of 0, 256, 512, 1024, 2048, 4096, 8192, 16384.\n * @return {SoundModule} This is returned for method chain.\n */\n resize(bufferSize) {\n this.init(this.context, bufferSize);\n return this;\n }\n\n /**\n * This method gets buffer size for `ScriptProcessorNode`.\n * @return {number} This is returned as buffer size for `ScriptProcessorNode`.\n */\n getBufferSize() {\n return this.processor.bufferSize;\n }\n\n /**\n * This method installs customized effector.\n * @param {string} name This argument is in order to select effector.\n * @param {Effector} effector This argument is the subclass that extends `Effector` class.\n * @return {SoundModule} This is returned for method chain.\n */\n install(name, effector) {\n if (!(effector instanceof Effector)) {\n return this;\n }\n\n if (String(name) in this) {\n return this;\n }\n\n this[name] = effector;\n\n if (this.modules.every(module => module !== effector)) {\n this.modules.push(effector);\n }\n\n return this;\n }\n\n /**\n * This method connects nodes that are defined by this library and Web Audio API.\n * @param {AudioNode} source This argument is `AudioNode` for input of sound.\n * @param {Array.<Effector>} connects This argument is array for changing the default connection.\n * @return {SoundModule} This is returned for method chain.\n */\n connect(source, connects) {\n // Customize connection ?\n if (Array.isArray(connects)) {\n this.modules = connects;\n }\n\n // Start connection\n // AudioSourceNode (Input)-> node -> ... -> node -> GainNode (Master Volume) -> AnalyserNode -> AudioDestinationNode (Output)\n source.disconnect(0); // Clear connection\n\n if (this.modules.length > 0) {\n source.connect(this.modules[0].INPUT);\n } else {\n source.connect(this.mastervolume);\n }\n\n for (let i = 0, len = this.modules.length; i < len; i++) {\n // Clear connection\n this.modules[i].OUTPUT.disconnect(0);\n\n if (i < (this.modules.length - 1)) {\n // Connect to next node\n this.modules[i].OUTPUT.connect(this.modules[i + 1].INPUT);\n } else {\n this.modules[i].OUTPUT.connect(this.mastervolume);\n }\n }\n\n this.mastervolume.connect(this.context.destination);\n\n // for analyser\n this.mastervolume.connect(this.analyser.INPUT);\n\n // for recording\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.INPUT.connect(this.context.destination);\n\n // for session\n this.mastervolume.connect(this.session.INPUT);\n this.session.INPUT.connect(this.context.destination);\n\n return this;\n }\n\n /**\n * This method gets the instance of module that is defined by this library. This method enables to access the instance of module by unified call.\n * @param {string} module This argument is module's name.\n * @return {Analyser|Recorder|Session|Effector|Listener|EnvelopeGenerator|Glide|VocalCanceler|NoiseGate|NoiseSuppressor} This value is the instance of module.\n */\n module(module) {\n const m = String(module).replace(/-/g, '').toLowerCase();\n\n switch (m) {\n case 'analyser' :\n case 'recorder' :\n case 'session' :\n case 'stereo' :\n case 'compressor' :\n case 'distortion' :\n case 'wah' :\n case 'pitchshifter' :\n case 'equalizer' :\n case 'filter' :\n case 'autopanner' :\n case 'tremolo' :\n case 'ringmodulator':\n case 'phaser' :\n case 'flanger' :\n case 'chorus' :\n case 'delay' :\n case 'reverb' :\n case 'panner' :\n case 'listener' :\n return this[m];\n case 'envelopegenerator':\n case 'eg' :\n return this.envelopegenerator;\n case 'glide':\n if (m in this) {\n return this[m]; // OscillatorModule\n }\n\n // fall through\n case 'vocalcanceler':\n if (m in this) {\n return this[m]; // AudioModule, MediaModule\n }\n\n // fall through\n case 'noisegate' :\n case 'noisesuppressor':\n if (m in this) {\n return this[m]; // StreamModule\n }\n\n // fall through\n default:\n return this[m]; // Installed effector\n }\n }\n\n /**\n * This method starts effectors.\n * @param {number} startTime This argument is used for scheduling parameter.\n * @return {SoundModule} This is returned for method chain.\n */\n on(startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.stereo.start(s);\n this.chorus.start(s);\n this.flanger.start(s);\n this.phaser.start(s);\n this.autopanner.start(s);\n this.tremolo.start(s);\n this.ringmodulator.start(s);\n this.wah.start(s);\n this.filter.start(s);\n\n return this;\n }\n\n /**\n * This method stops effectors.\n * @param {number} stopTime This argument is used for scheduling parameter.\n * @return {SoundModule} This is returned for method chain.\n */\n off(stopTime) {\n let s = parseFloat(stopTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n this.stereo.stop(s);\n this.chorus.stop(s);\n this.flanger.stop(s);\n this.phaser.stop(s);\n this.autopanner.stop(s);\n this.tremolo.stop(s);\n this.ringmodulator.stop(s);\n this.wah.stop(s);\n // this.filter.stop(s);\n\n return this;\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {object}\n */\n params() {\n const params = {};\n\n for (const module in this) {\n if (Object.prototype.toString.call(this[module]) === '[object Function]') {\n continue;\n }\n\n const m = module.toLowerCase();\n\n if (m === 'mastervolume') {\n params[m] = this[module].gain.value; // AudioParam\n } else if ((Object.prototype.toString.call(this[module]) === '[object Object]') && ('params' in this[module])) {\n params[m] = this[module].params();\n }\n }\n\n return params;\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n toJSON() {\n return JSON.stringify(this.params());\n }\n\n /** @override */\n toString() {\n return '[SoundModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for the instance of `OscillatorNode`.\n * @constructor\n */\nexport class Oscillator {\n // 1 Octave = 1200 cent\n static OCTAVE = 1200;\n\n // for legacy browsers\n static WAVE_TYPES = {\n 'sine' : 0,\n 'square' : 1,\n 'sawtooth' : 2,\n 'triangle' : 3\n };\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {boolean} state This argument is initial state.\n */\n constructor(context, state) {\n this.isActive = state;\n\n this.context = context;\n\n this.source = context.createOscillator();\n\n // for legacy browsers\n this.source.setPeriodicWave = this.source.setPeriodicWave || this.source.setWaveTable;\n this.source.start = this.source.start || this.source.noteOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n this.volume = context.createGain();\n\n // in order to not call in duplicate `start` or `stop` method in the instance of `OscillatorNode`\n this.isStop = true;\n\n this.octave = 0;\n this.fine = 0;\n this.customs = {\n 'real' : new Float32Array([0, 1]),\n 'imag' : new Float32Array([0, 1])\n };\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|string|Oscillator} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.source.type;\n }\n\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n v = String(value).toLowerCase();\n\n if (v in Oscillator.WAVE_TYPES) {\n this.source.type = (typeof this.source.type === 'string') ? v : Oscillator.WAVE_TYPES[v];\n }\n } else {\n // Custom wave\n if (('real' in value) && ('imag' in value)) {\n let reals = null;\n let imags = null;\n\n if (value.real instanceof Float32Array) {\n reals = value.real;\n } else if (Array.isArray(value.real)) {\n reals = new Float32Array(value.real);\n }\n\n if (value.imag instanceof Float32Array) {\n imags = value.imag;\n } else if (Array.isArray(value.imag)) {\n imags = new Float32Array(value.imag);\n }\n\n if ((reals instanceof Float32Array) && (imags instanceof Float32Array)) {\n const MAX_SIZE = 4096; // This size is defined by specification\n\n if (reals.length > MAX_SIZE) { reals = reals.subarray(0, MAX_SIZE); }\n if (imags.length > MAX_SIZE) { imags = imags.subarray(0, MAX_SIZE); }\n\n // The 1st value is fixed by 0 (This is is defined by specification)\n if (reals[0] !== 0) { reals[0] = 0; }\n if (imags[0] !== 0) { imags[0] = 0; }\n\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n this.customs.real = reals;\n this.customs.imag = imags;\n }\n }\n }\n\n break;\n case 'octave':\n if (value === undefined) {\n return this.octave;\n }\n\n v = parseFloat(value);\n min = -4800 / Oscillator.OCTAVE;\n max = 4800 / Oscillator.OCTAVE;\n\n if ((v >= min) && (v <= max)) {\n this.octave = v;\n this.source.detune.value = this.fine + (v * Oscillator.OCTAVE);\n }\n\n break;\n case 'fine':\n if (value === undefined) {\n return this.fine;\n }\n\n v = parseFloat(value);\n min = -Oscillator.OCTAVE;\n max = Oscillator.OCTAVE;\n\n if ((v >= min) && (v <= max)) {\n this.fine = v;\n this.source.detune.value = v + (this.octave * Oscillator.OCTAVE);\n }\n\n break;\n case 'volume':\n case 'gain' :\n if (value === undefined) {\n return this.volume.gain.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.volume.gain.value = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method connects nodes.\n * @param {AudioNode} output This argument is the instance of `AudioNode` as output.\n * @return {Oscillator} This is returned for method chain.\n */\n ready(output) {\n if (this.isActive) {\n // for saving value\n const params = {\n 'type' : this.source.type,\n 'frequency' : this.source.frequency.value,\n 'detune' : this.source.detune.value\n };\n\n if (!this.isStop) {\n this.source.stop(this.context.currentTime);\n this.source.disconnect(0);\n }\n\n this.source = this.context.createOscillator();\n\n // for legacy browsers\n this.source.setPeriodicWave = this.source.setPeriodicWave || this.source.setWaveTable;\n this.source.start = this.source.start || this.source.noteOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n if (params.type === 'custom') {\n // Custom wave\n const reals = this.customs.real;\n const imags = this.customs.imag;\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n } else {\n this.source.type = params.type;\n }\n\n this.source.frequency.value = params.frequency;\n this.source.detune.value = params.detune;\n\n this.volume.connect(output);\n }\n\n return this;\n }\n\n /**\n * This method starts sound.\n * @param {number} startTime This argument is the start time.\n * @return {Oscillator} This is returned for method chain.\n */\n start(startTime) {\n if (this.isActive) {\n this.source.start(startTime);\n this.isStop = false;\n } else {\n if (!this.isStop) {\n this.source.stop(this.context.currentTime);\n this.isStop = true;\n }\n\n this.source.disconnect(0);\n }\n\n return this;\n }\n\n /**\n * This method stops sound.\n * @param {number} stopTime This argument is the stop time.\n * @return {Oscillator} This is returned for method chain.\n */\n stop(stopTime) {\n if (!this.isStop) {\n this.source.stop(stopTime);\n this.source.disconnect(0);\n\n this.isStop = true;\n }\n\n return this;\n }\n\n /**\n * This method toggles active state or inactive state.\n * @param {boolean|string} state If this argument is boolean, state is changed the designated.\n * If this argument is 'toggle', state is changed automatically.\n * If this argument is omitted, this method is getter.\n * @return {boolean|Oscillator} This is returned as current state. Otherwise, this is returned for method chain.\n */\n state(state) {\n if (state === undefined) {\n return this.isActive;\n }\n\n if (String(state).toLowerCase() === 'toggle') {\n this.isActive = !this.isActive;\n } else {\n this.isActive = Boolean(state);\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `OscillatorNode`.\n * @return {OscillatorNode}\n */\n get() {\n return this.source;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule Oscillator]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Glide.\n * @constructor\n */\nexport class Glide {\n static LINEAR = 'linear';\n static EXPONENTIAL = 'exponential';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.frequencies = {\n 'start' : -1, // Abnormal value for the 1st sound\n 'end' : 0\n };\n\n this.time = 0; // Glide time\n this.type = Glide.LINEAR; // either 'linear' or 'exponential'\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|Glide} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n\n switch (k) {\n case 'time':\n if (value === undefined) {\n return this.time;\n }\n\n v = parseFloat(value);\n\n if (v >= 0) {\n this.time = v;\n }\n\n break;\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === Glide.LINEAR) || (v === Glide.EXPONENTIAL)) {\n this.type = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method sets frequencies for Glide.\n * @param {number} frequency This argument is the frequency at which glide ends.\n * @return {Glide} This is returned for method chain.\n */\n ready(frequency) {\n this.frequencies.end = frequency;\n\n const diff = (this.frequencies.start === -1) ? 0 : (this.frequencies.end - this.frequencies.start);\n\n if ((this.frequencies.start === -1) || (this.time === 0) || (diff === 0)) {\n // The 1st sound or Glide OFF or The same sound\n this.frequencies.start = this.frequencies.end;\n }\n\n return this;\n }\n\n /**\n * This method starts Glide.\n * @param {OscillatorNode} oscillator This argument is the instance of `OscillatorNode`.\n * @param {number} startTime This argument is the start time of Glide.\n * @return {Glide} This is returned for method chain.\n */\n start(oscillator, startTime) {\n let s = parseFloat(startTime);\n\n if (isNaN(s) || (s < this.context.currentTime)) {\n s = this.context.currentTime;\n }\n\n const t0 = s;\n const t1 = t0 + this.time;\n\n // Start Glide\n oscillator.frequency.cancelScheduledValues(t0);\n oscillator.frequency.setValueAtTime(this.frequencies.start, t0);\n oscillator.frequency[`${this.type}RampToValueAtTime`](this.frequencies.end, t1);\n\n return this;\n }\n\n /**\n * This method stops Glide. Moreover, This method prepares for next Glide.\n * @return {Glide} This is returned for method chain.\n */\n stop() {\n // Stop Glide or on the way of Glide\n this.frequencies.start = this.frequencies.end;\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule Glide]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { Oscillator } from './Oscillator';\nimport { Glide } from './Glide';\n\n/**\n * This subclass defines properties for creating sound.\n * Actually, properties for creating sound is defined in private class (`Oscillator`).\n * Therefore, this class manages these private classes for creating sound.\n * @constructor\n * @extends {SoundModule}\n */\nexport class OscillatorModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n /** @type {Array.<Oscillator>} */\n this.sources = [];\n\n // for scheduling\n this.times = {\n 'start' : 0,\n 'duration' : 0\n };\n\n // This flag determines whether sound wave is drawn\n this.isAnalyser = false;\n\n this.glide = new Glide(context);\n }\n\n /**\n * This method creates the instances of `Oscillator`.\n * @param {Array.<boolean>|boolean} states This argument is initial state in the instance of `Oscillator`.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n setup(states) {\n // Clear\n this.sources.length = 0;\n\n if (!Array.isArray(states)) {\n states = [states];\n }\n\n for (let i = 0, len = states.length; i < len; i++) {\n this.sources[i] = new Oscillator(this.context, Boolean(states[i]));\n this.envelopegenerator.setGenerator(i);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|OscillatorModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n return (r === undefined) ? this : r;\n }\n }\n\n /**\n * This method schedules the time of start and stop.\n * @param {number} startTime This argument is the start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n ready(startTime, duration) {\n const s = parseFloat(startTime);\n const d = parseFloat(duration);\n\n this.times.start = (s >= 0) ? s : 0;\n this.times.duration = (d >= 0) ? d : 0;\n\n this.envelopegenerator.clear(true);\n\n return this;\n }\n\n /**\n * This method starts some sounds that are active at the same time.\n * @param {Array.<number>}|number} frequencies This argument each oscillator frequency. The default value is 0 Hz.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n start(frequencies, connects, processCallback) {\n const startTime = this.context.currentTime + this.times.start;\n\n // Validate the 1st argument\n if (!Array.isArray(frequencies)) {\n frequencies = [frequencies];\n }\n\n for (let i = 0, len = frequencies.length; i < len; i++) {\n const f = parseFloat(frequencies[i]);\n frequencies[i] = (f >= 0) ? f : 0;\n }\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // ScriptProcessorNode (Mix oscillators) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor, connects);\n\n for (let i = 0, len = frequencies.length; i < len; i++) {\n if (i >= this.sources.length) {\n break;\n }\n\n const oscillator = this.sources[i];\n const frequency = frequencies[i];\n\n // GainNode (Volume) -> ScriptProcessorNode (Mix oscillators)\n oscillator.ready(this.processor);\n\n // OscillatorNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume)\n this.envelopegenerator.ready(i, oscillator.source, oscillator.volume);\n\n this.glide.ready(frequency).start(oscillator.source, startTime);\n\n oscillator.start(startTime);\n }\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n // Stop ?\n if (this.envelopegenerator.isStop()) {\n // Stop\n const stopTime = this.context.currentTime;\n\n for (const source of this.sources) {\n source.stop(stopTime);\n }\n\n this.off(stopTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method stops active sounds.\n * @return {OscillatorModule} This is returned for method chain.\n * @override\n */\n stop() {\n const stopTime = this.context.currentTime + this.times.start + this.times.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.glide.stop();\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets the instance of `Oscillator` that is used in `OscillatorModule`.\n * @param {number} index This argument is required in the case of designating `Oscillator`.\n * @return {Array.<Oscillator>|Oscillator}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /**\n * This method returns the number of oscillators.\n * @return {number} This is returned as the number of oscillators.\n */\n length() {\n return this.sources.length;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.oscillator = {\n 'glide' : {\n 'type' : this.glide.param('type'),\n 'time' : this.glide.param('time')\n }\n };\n\n for (let i = 0, len = this.sources.length; i < len; i++) {\n const source = this.sources[i];\n\n params.oscillator[`oscillator${i}`] = {\n 'state' : source.state(),\n 'gain' : source.param('gain'),\n 'type' : source.param('type'),\n 'octave' : source.param('octave'),\n 'fine' : source.param('fine')\n };\n }\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[OscillatorModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\n/**\n * This subclass defines properties for playing the one-shot audio.\n * @constructor\n * @extends {SoundModule}\n */\nexport class OneshotModule extends SoundModule {\n static ERROR_AJAX = 'error';\n static ERROR_AJAX_TIMEOUT = 'timeout';\n static ERROR_DECODE = 'decode';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.sources = []; /** @type {Array.<AudioBufferSourceNode>} */\n this.resources = []; /** @type {Array.<string>} */\n this.buffers = []; /** @type {Array.<AudioBuffer>} */\n this.volumes = []; /** @type {Array.<GainNode>} */\n this.isStops = []; /** @type {Array.<boolean>} in order to not call in duplicate `start` or `stop` method in the instance of `AudioBufferSourceNode` */\n\n // for audio sources\n this.settings = []; /** @type {Array.<object>} */\n\n // for scheduling\n this.times = {\n 'start' : 0,\n 'duration' : 0\n };\n\n this.transpose = 1.0;\n\n this.isStop = true;\n\n // If the error is at least 1, this method aborts the all of connections.\n // Therefore, this flag are shared with the all instances of `XMLHttpRequest`.\n this.isLoadError = false;\n\n // This flag determines whether sound wave is drawn\n this.isAnalyser = false;\n }\n\n /**\n * This method creates the instances of `AudioBuffer` by Ajax.\n * @param {Array.<string>|Array.<AudioBuffer>} resources This argument is either URLs or the instances of `AudioBuffer` for audio resources.\n * @param {Array.<object>} settings This argument is the properties of each audio sources.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n setup(resources, settings, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('resources' in properties) {\n resources = properties.resources;\n }\n\n if ('settings' in properties) {\n settings = properties.settings;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!Array.isArray(resources)) {\n resources = [resources];\n }\n\n this.resources = resources;\n\n if (!Array.isArray(settings)) {\n settings = [settings];\n }\n\n this.buffers.length = resources.length;\n\n for (let i = 0, len = settings.length; i < len; i++) {\n if ('buffer' in settings[i]) {\n const buffer = parseInt(settings[i].buffer, 10);\n\n if ((buffer >= 0) && (buffer < this.buffers.length)) {\n settings[i].buffer = buffer;\n } else {\n return this;\n }\n } else {\n return this;\n }\n\n settings[i].rate = (('rate' in settings[i]) && (settings[i].rate >= 0)) ? parseFloat(settings[i].rate) : 1;\n settings[i].loop = ('loop' in settings[i]) ? Boolean(settings[i].loop) : false;\n settings[i].start = (('start' in settings[i]) && (settings[i].start >= 0)) ? parseFloat(settings[i].start) : 0;\n settings[i].end = (('end' in settings[i]) && (settings[i].end >= 0)) ? parseFloat(settings[i].end) : 0;\n settings[i].volume = (('volume' in settings[i]) && (settings[i].volume >= 0) && (settings[i].volume <= 1)) ? parseFloat(settings[i].volume) : 1;\n\n this.isStops[i] = true;\n this.volumes[i] = this.context.createGain();\n this.envelopegenerator.setGenerator(i);\n }\n\n this.settings = settings;\n\n const t = parseInt(timeout, 10);\n\n for (let i = 0, len = this.resources.length; i < len; i++) {\n if (typeof this.resources[i] === 'string') {\n // Get the instances of `AudioBuffer` from the designated URLs.\n this.load(this.resources[i], i, t, successCallback, errorCallback, progressCallback);\n } else if (this.resources[i] instanceof AudioBuffer) {\n // Get the instances of `AudioBuffer` directly\n this.buffers[i] = this.resources[i];\n }\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|OneshotModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n\n switch (k) {\n case 'transpose':\n if (value === undefined) {\n return this.transpose;\n }\n\n v = parseFloat(value);\n\n if (v > 0) {\n this.transpose = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method schedules the time of start and stop.\n * @param {number} startTime This argument is the start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n ready(startTime, duration) {\n const s = parseFloat(startTime);\n const d = parseFloat(duration);\n\n this.times.start = (s >= 0) ? s : 0;\n this.times.duration = (d >= 0) ? d : 0;\n\n this.envelopegenerator.clear(false);\n\n return this;\n }\n\n /**\n * This method starts one-shot audio with the designated playback rate and volume.\n * @param {number} index This argument is in order to select the instance of `AudioBufferSourceNode`.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n start(index, connects, processCallback) {\n const selectedIndex = parseInt(index, 10);\n\n if (isNaN(selectedIndex) || (selectedIndex < 0) || (selectedIndex >= this.settings.length)) {\n return this;\n }\n\n const bufferIndex = this.settings[selectedIndex].buffer;\n const playbackRate = this.settings[selectedIndex].rate;\n const loop = this.settings[selectedIndex].loop;\n const loopStart = this.settings[selectedIndex].start;\n const loopEnd = this.settings[selectedIndex].end;\n const volume = this.settings[selectedIndex].volume;\n\n if (!(this.buffers[bufferIndex] instanceof AudioBuffer)) {\n // `setup` method has not been invoked\n return this;\n }\n\n // The following code is unnecessary, because `AudioBufferSourceNode` is the target of garbage collection in the case of no references and no sound\n // (If there is this code, application cannot repeat hits).\n\n // if (this.sources[selectedIndex] instanceof AudioBufferSourceNode) {\n // this.sources[selectedIndex].stop(this.context.currentTime);\n // this.sources[selectedIndex].disconnect(0);\n // this.sources[selectedIndex] = null;\n // }\n\n const source = this.context.createBufferSource();\n\n // for legacy browsers\n source.start = source.start || source.noteGrainOn;\n source.stop = source.stop || source.noteOff;\n\n source.buffer = this.buffers[bufferIndex];\n\n // Set properties\n source.playbackRate.value = playbackRate * this.transpose;\n source.loop = loop;\n source.loopStart = loopStart;\n source.loopEnd = loopEnd;\n\n this.volumes[selectedIndex].gain.value = volume;\n\n this.envelopegenerator.clear(false);\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(selectedIndex, source, this.volumes[selectedIndex]);\n this.volumes[selectedIndex].connect(this.processor);\n this.connect(this.processor, connects);\n\n const startTime = this.context.currentTime + this.times.start;\n\n if (source.loop) {\n source.start(startTime, (startTime + source.loopStart), (source.loopEnd - startTime));\n } else {\n source.start(startTime);\n }\n\n this.sources[selectedIndex] = source;\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.isStops[selectedIndex] = false;\n\n // in the case of scheduling stop time\n if (this.times.stop > 0) {\n window.setTimeout(() => {\n this.stop(selectedIndex);\n }, (this.times.stop * 1000));\n }\n\n // Call on stopping audio\n source.onended = () => {\n this.isStops[selectedIndex] = true;\n };\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n this.isStop = this.isStops.every(element => element);\n\n if (this.isStop) {\n // Stop\n\n this.off(this.context.currentTime);\n\n this.envelopegenerator.clear(false);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method stops the designated one-shot audio.\n * @param {number} index This argument is in order to select the instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} This is returned for method chain.\n * @override\n */\n stop(index) {\n const selectedIndex = parseInt(index, 10);\n\n if (isNaN(selectedIndex) || (selectedIndex < 0) || (selectedIndex >= this.settings.length)) {\n return this;\n }\n\n const bufferIndex = this.settings[selectedIndex].buffer;\n\n if (!((this.buffers[bufferIndex] instanceof AudioBuffer) && (this.sources[selectedIndex] instanceof AudioBufferSourceNode))) {\n return this;\n }\n\n const stopTime = this.context.currentTime + this.times.start + this.times.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets the instance of `AudioBuffer` that is used in `OneshotModule`.\n * @param {number} index This argument is required in the case of designating `AudioBuffer`.\n * @return {Array.<AudioBuffer>|AudioBuffer}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.buffers.length)) ? this.buffers[i] : this.buffers;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.oneshot = {\n 'transpose' : this.transpose\n };\n\n return params;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates the instances of `AudioBuffer`.\n * @param {string} url This argument is resource URL for one-shot audio.\n * @param {number} index This argument is in order to assign the instance of `AudioBuffer`.\n * @param {number} timeout This argument is Ajax timeout.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n * @return {OneshotModule} This is returned for method chain.\n */\n load(url, index, timeout, successCallback, errorCallback, progressCallback) {\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = (timeout > 0) ? timeout : 60000;\n\n xhr.ontimeout = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, OneshotModule.ERROR_AJAX_TIMEOUT);\n }\n\n this.isLoadError = true;\n };\n\n xhr.onprogress = event => {\n if (this.isLoadError) {\n xhr.abort();\n } else if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (!this.isLoadError && (Object.prototype.toString.call(errorCallback) === '[object Function]')) {\n errorCallback(event, OneshotModule.ERROR_AJAX);\n }\n\n this.isLoadError = true;\n };\n\n // Success\n xhr.onload = event => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = audioBuffer => {\n this.buffers[index] = audioBuffer;\n\n // The creating the instances of `AudioBuffer` has completed ?\n for (const buffer of this.buffers) {\n if (buffer === undefined) {\n return;\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(event, this.buffers);\n }\n };\n\n const decodeErrorCallback = error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error, OneshotModule.ERROR_DECODE);\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n\n return this;\n }\n\n /**\n * This method resets settings.\n * @param {number} index This argument is in order to select target setting.\n * @param {string} key This argument is in order to select parameter.\n * @param {number|boolean} value This argument is new value.\n * @return {OneshotModule} This is returned for method chain.\n */\n reset(index, key, value) {\n const selectedIndex = parseInt(index, 10);\n\n if (String(key).toLowerCase() in this.settings[selectedIndex]) {\n this.settings[selectedIndex][key.toLowerCase()] = value;\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[OneshotModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\nexport class NoiseModule extends SoundModule {\n static WHITE_NOISE = 'whitenoise';\n static PINK_NOISE = 'pinknoise';\n static BROWNIAN_NOISE = 'browniannoise';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.type = NoiseModule.WHITE_NOISE;\n\n this.envelopegenerator.setGenerator(0);\n\n this.isAnalyser = false;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|string} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|string|NoiseModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = '';\n\n switch (k) {\n case 'type':\n if (value === undefined) {\n return this.type;\n }\n\n v = String(value).toLowerCase();\n\n if ((v === NoiseModule.WHITE_NOISE) || (v === NoiseModule.PINK_NOISE) || (v === NoiseModule.BROWNIAN_NOISE)) {\n this.type = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /** @override */\n start(connects) {\n const startTime = this.context.currentTime;\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(this.envelopegenerator.getGenerator(0), connects);\n\n // ScriptProcessorNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.on(startTime);\n\n const bufferSize = this.processor.bufferSize;\n\n let lastOut = 0;\n\n this.processor.onaudioprocess = event => {\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.envelopegenerator.isStop()) {\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n } else {\n switch (this.type) {\n case NoiseModule.WHITE_NOISE:\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = 2 * (Math.random() - 0.5);\n outputRs[i] = 2 * (Math.random() - 0.5);\n }\n\n break;\n case NoiseModule.PINK_NOISE:\n // ref: https://noisehack.com/generate-noise-web-audio-api/\n let b0 = 0;\n let b1 = 0;\n let b2 = 0;\n let b3 = 0;\n let b4 = 0;\n let b5 = 0;\n let b6 = 0;\n\n for (let i = 0; i < bufferSize; i++) {\n const white = (Math.random() * 2) - 1;\n\n b0 = (0.99886 * b0) + (white * 0.0555179);\n b1 = (0.99332 * b1) + (white * 0.0750759);\n b2 = (0.96900 * b2) + (white * 0.1538520);\n b3 = (0.86650 * b3) + (white * 0.3104856);\n b4 = (0.55000 * b4) + (white * 0.5329522);\n b5 = (-0.7616 * b5) - (white * 0.0168980);\n\n outputLs[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + (white * 0.5362);\n outputRs[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + (white * 0.5362);\n\n outputLs[i] *= 0.11;\n outputRs[i] *= 0.11;\n\n b6 = white * 0.115926;\n }\n\n break;\n case NoiseModule.BROWNIAN_NOISE:\n // ref: https://noisehack.com/generate-noise-web-audio-api/\n for (let i = 0; i < bufferSize; i++) {\n const white = (Math.random() * 2) - 1;\n\n outputLs[i] = (lastOut + (0.02 * white)) / 1.02;\n outputRs[i] = (lastOut + (0.02 * white)) / 1.02;\n\n lastOut = (lastOut + (0.02 * white)) / 1.02;\n\n outputLs[i] *= 3.5;\n outputRs[i] *= 3.5;\n }\n\n break;\n default:\n break;\n }\n }\n };\n\n return this;\n }\n\n /** @override */\n stop() {\n const stopTime = this.context.currentTime;\n\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[NoiseModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Vocal Canceler.\n * @constructor\n */\nexport class VocalCanceler {\n constructor() {\n this.depth = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|VocalCanceler} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'depth':\n if (value === undefined) {\n return this.depth;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.depth = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method removes vocal part in the played audio.\n * @param {number} dataL This argument is gain level for Left channel.\n * @param {number} dataR This argument is gain level for Right channel.\n * @return {number} This is returned as audio data except vocal part.\n */\n start(dataL, dataR) {\n return dataL - (this.depth * dataR);\n }\n\n /** @override */\n toString() {\n return '[AudioModule VocalCanceler]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { VocalCanceler } from './VocalCanceler';\n\n/**\n * This subclass defines properties for playing the single audio.\n * This class creates audio player that has higher features than `HTMLAudioElment`.\n * But, this class is disadvantage to play the many one shot audios.\n * In the case of that, developer should use `OneshotModule`.\n * @constructor\n * @extends {SoundModule}\n */\nexport class AudioModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.source = context.createBufferSource(); // for the instance of `AudioBufferSourceNode`\n this.buffer = null; // for the instance of `AudioBuffer`\n\n this.currentTime = 0;\n\n this.paused = true;\n\n this.callbacks = {\n 'decode' : () => {},\n 'ready' : () => {},\n 'start' : () => {},\n 'stop' : () => {},\n 'update' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n\n this.vocalcanceler = new VocalCanceler();\n }\n\n /**\n * This method sets callback functions.\n * @param {string|object} key This argument is property name.\n * This argument is pair of property and value in the case of associative array.\n * @param {function} value This argument is callback function.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n setup(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.setup(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(value) === '[object Function]') {\n this.callbacks[k] = value;\n }\n }\n }\n\n this.envelopegenerator.setGenerator(0);\n this.envelopegenerator.param({\n 'attack' : 0,\n 'decay' : 0.01,\n 'sustain' : 1,\n 'release' : 0.01\n });\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n let v = 0;\n let min = 0;\n let max = 0;\n\n switch (k) {\n case 'playbackrate':\n if (value === undefined) {\n return this.source.playbackRate.value;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1024;\n\n if ((v >= min) && (v <= max)) {\n this.source.playbackRate.value = v;\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / v)), true);\n }\n\n break;\n case 'loop' :\n case 'looping':\n if (value === undefined) {\n return this.source.loop;\n }\n\n this.source.loop = Boolean(value);\n\n break;\n case 'currenttime':\n if (value === undefined) {\n return this.currentTime;\n }\n\n if (this.buffer instanceof AudioBuffer) {\n v = parseFloat(value);\n max = this.buffer.duration;\n min = 0;\n\n if ((v >= min) && (v <= max)) {\n if (this.paused) {\n this.currentTime = v;\n } else {\n this.stop();\n this.start(v);\n }\n }\n } else {\n this.currentTime = 0;\n }\n\n break;\n case 'duration':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.duration : 0; // Getter only\n case 'samplerate':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.sampleRate : this.sampleRate; // Getter only\n case 'channels':\n return (this.buffer instanceof AudioBuffer) ? this.buffer.numberOfChannels : 0; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method creates the instance of `AudioBuffer` from `ArrayBuffer` or sets the instanceof `AudioBuffer`.\n * @param {ArrayBuffer|AudioBuffer} buffer This argument is the instance of `ArrayBuffer` or `AudioBuffer`.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n ready(buffer) {\n if (buffer instanceof ArrayBuffer) {\n this.buffer = null;\n\n const successCallback = b => {\n this.buffer = b;\n\n this.analyser.start('timeoverview', 0, this.buffer);\n this.analyser.start('timeoverview', 1, this.buffer);\n\n this.callbacks.ready(this.buffer);\n };\n\n this.context.decodeAudioData(buffer, successCallback, this.callbacks.error);\n\n this.callbacks.decode(buffer);\n } else if (buffer instanceof AudioBuffer) {\n this.buffer = buffer;\n }\n\n return this;\n }\n\n /**\n * This method starts audio from the designated time.\n * @param {number} startTime This argument is the time that audio is started at. The default value is 0.\n * @param {number} endTime This argument is the time that audio is ended at. The default value is audio duration.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n start(startTime, endTime, connects, processCallback) {\n if ((this.buffer instanceof AudioBuffer) && this.paused) {\n // This value is `AudioContext#currentTime`\n const currentTime = this.context.currentTime;\n\n const start = parseFloat(startTime);\n const end = parseFloat(endTime);\n\n if (end >= 0) {\n this.currentTime = ((start >= 0) && (start <= end)) ? start : 0;\n } else {\n this.currentTime = ((start >= 0) && (start <= this.buffer.duration)) ? start : 0;\n }\n\n const playbackRate = this.source.playbackRate.value;\n const loop = this.source.loop;\n\n this.source = this.context.createBufferSource();\n\n // for legacy browsers\n this.source.start = this.source.start || this.source.noteGrainOn;\n this.source.stop = this.source.stop || this.source.noteOff;\n\n this.source.buffer = this.buffer;\n this.source.playbackRate.value = playbackRate;\n this.source.loop = loop;\n this.source.loopStart = this.currentTime;\n this.source.loopEnd = (end >= 0) ? end : this.buffer.duration;\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor, connects);\n\n if (isNaN(start)) {\n this.source.start(currentTime);\n } else if (end >= 0) {\n this.source.start(currentTime, this.currentTime, (end - start));\n } else {\n this.source.start(currentTime, this.currentTime, (this.buffer.duration - this.currentTime));\n }\n\n this.analyser.start('time');\n this.analyser.start('fft');\n\n this.paused = false;\n\n this.envelopegenerator.start(currentTime);\n\n if (end >= 0) {\n this.envelopegenerator.stop((currentTime + ((end - start) / this.source.playbackRate.value)), true);\n } else {\n this.envelopegenerator.stop((currentTime + ((this.buffer.duration - start) / this.source.playbackRate.value)), true);\n }\n\n this.on(currentTime);\n\n this.callbacks.start(this.source, this.currentTime);\n\n const bufferSize = this.processor.bufferSize;\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n if (this.currentTime < Math.floor(this.source.loopEnd)) {\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.vocalcanceler.start(inputLs[i], inputRs[i]);\n outputRs[i] = this.vocalcanceler.start(inputRs[i], inputLs[i]);\n\n this.currentTime += ((1 * this.source.playbackRate.value) / this.source.buffer.sampleRate);\n\n this.callbacks.update(this.source, this.currentTime);\n }\n\n this.analyser.domain('timeoverview', 0).update(this.currentTime);\n this.analyser.domain('timeoverview', 1).update(this.currentTime);\n } else {\n if (this.source.loop) {\n this.stop();\n\n if ((this.analyser.domain('timeoverview', 0).param('mode') === 'sprite') || (this.analyser.domain('timeoverview', 1).param('mode') === 'sprite')) {\n this.start(this.source.loopStart, this.source.loopEnd, connects, processCallback);\n } else {\n this.start(0, this.buffer.duration, connects, processCallback);\n }\n } else {\n this.end();\n }\n }\n };\n }\n }\n\n return this;\n }\n\n /**\n * This method stops audio.\n * @return {AudioModule} This is returned for method chain.\n * @override\n */\n stop() {\n if ((this.buffer instanceof AudioBuffer) && !this.paused) {\n const stopTime = this.context.currentTime;\n\n this.source.stop(stopTime);\n\n this.off(stopTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Clear\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.paused = true;\n this.callbacks.stop(this.source, this.currentTime);\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `AudioBufferSourceNode`.\n * @return {AudioBufferSourceNode}\n * @override\n */\n get() {\n return this.source;\n }\n\n /**\n * This method starts or stops audio according to audio state.\n * @param {number} startTime This argument is the time that audio is started at. The default value is 0.\n * @param {number} endTime This argument is the time that audio is ended at. The default value is audio duration.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {AudioModule} This is returned for method chain.\n */\n toggle(startTime, endTime, connects, processCallback) {\n if (this.paused) {\n this.start(startTime, endTime, connects, processCallback);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method rewinds audio.\n * @return {AudioModule} This is returned for method chain.\n */\n end() {\n this.stop();\n this.currentTime = 0;\n this.callbacks.ended(this.source, this.currentTime);\n\n return this;\n }\n\n /**\n * This method determines whether the instance of `AudioBuffer` exists.\n * @return {boolean} If the instance of `AudioBuffer` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isBuffer() {\n return this.buffer instanceof AudioBuffer;\n }\n\n /**\n * This method determines whether the instance of `AudioBufferSourceNode` exists.\n * @return {boolean} If the instance of `AudioBufferSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isSource() {\n return (this.source instanceof AudioBufferSourceNode) && (this.source.buffer instanceof AudioBuffer);\n }\n\n /**\n * This method determines whether the audio is paused.\n * @return {boolean} If the audio is paused, this value is `true`. Otherwise, this value is `false`.\n */\n isPaused() {\n return this.paused;\n }\n\n /**\n * This method is getter or setter for fade-in time.\n * @param {number} time This argument is fade-in time. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as fade-in time. Otherwise, this is returned for method chain.\n */\n fadeIn(time) {\n if (time === undefined) {\n return this.envelopegenerator.param('attack');\n }\n\n this.envelopegenerator.param('attack', time);\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n\n return this;\n }\n\n /**\n * This method is getter or setter for fade-out time.\n * @param {number} time This argument is fade-out time. If this argument is omitted, This method is getter.\n * @return {number|AudioModule} This is returned as fade-out time. Otherwise, this is returned for method chain.\n */\n fadeOut(time) {\n if (time === undefined) {\n return this.envelopegenerator.param('release');\n }\n\n this.envelopegenerator.param('release', time);\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n\n return this;\n }\n\n /**\n * This method slices the instance of `AudioBuffer`.\n * @param {number} startTime This argument is start time [sec] on `AudioBuffer`.\n * @param {number} endTime This argument is end time [sec] on `AudioBuffer`.\n * @return {AudioBuffer} This is returned as sliced `AudioBuffer`.\n */\n slice(startTime, endTime) {\n if (!this.isBuffer()) {\n return null;\n }\n\n const {\n sampleRate,\n length,\n numberOfChannels\n } = this.buffer;\n\n let start = Math.floor(startTime * sampleRate);\n let end = Math.floor(endTime * sampleRate);\n\n if (isNaN(start) || (start < 0)) {\n start = 0;\n }\n\n if (isNaN(end) || (end > length)) {\n end = length;\n }\n\n let dataLs = null;\n let dataRs = null;\n\n if (numberOfChannels > 0) {\n dataLs = this.buffer.getChannelData(0);\n }\n\n if (numberOfChannels > 1) {\n dataRs = this.buffer.getChannelData(1);\n }\n\n let bufferLs = null;\n let bufferRs = null;\n let buffer = null;\n\n const bufferSize = end - start;\n\n switch (numberOfChannels) {\n case 1:\n bufferLs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n }\n\n buffer = this.context.createBuffer(1, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n\n return buffer;\n case 2:\n bufferLs = new Float32Array(bufferSize);\n bufferRs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n bufferRs[i - start] = dataRs[i];\n }\n\n buffer = this.context.createBuffer(2, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n buffer.copyToChannel(bufferRs, 1);\n\n return buffer;\n default:\n return null;\n }\n }\n\n /**\n * This method sprites audio.\n * @param {object} sprites This argument is the associative array that contains sprite times.\n * @return {object} This is returned as the associative array that contains sprited `AudioBuffer`.\n */\n sprite(sprites) {\n if (!this.isBuffer()) {\n return null;\n }\n\n if (Object.prototype.toString.call(sprites) !== '[object Object]') {\n return null;\n }\n\n return Object.keys(sprites).reduce((audioBuffers, key) => {\n const times = sprites[key];\n\n if (!Array.isArray(times) || (times.length !== 2)) {\n return audioBuffers;\n }\n\n audioBuffers[key] = this.slice(parseFloat(times[0]), parseFloat(times[1]));\n\n return audioBuffers;\n }, {});\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.audio = {\n 'playbackrate' : this.isSource() ? this.source.playbackRate.value : 1,\n 'vocalcanceler' : {\n 'depth' : this.vocalcanceler.param('depth')\n }\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[AudioModule]';\n }\n}\n","'use strict';\n\nimport { AudioModule } from '../AudioModule';\n\n/**\n * This class defines properties for processing sound data from `HTMLMediaElement`.\n * Namely, this class creates audio player that has higher features from `HTMLMediaElement`.\n * But, this class is disadvantage to play the many one shot audios.\n * In the case of that, developer should use `OneshotModule`.\n * @constructor\n * @extends {AudioModule}\n */\nexport class MediaModule extends AudioModule {\n static AUDIO = 'audio';\n static VIDEO = 'video';\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.source = null; // for the instance of `MediaElementAudioSourceNode`\n this.media = null; // for the instance of `HTMLMediaElement`\n this.ext = ''; // 'wav', 'ogg', 'mp3, 'webm', 'ogv', 'mp4' ...etc\n\n // for Audio Streaming\n this.mse = null; // for the instance of `MediaSource`\n this.sb = null; // for the instance of `SourceBuffer`\n this.file = '';\n this.mimeType = '';\n\n this.playbackRate = 1;\n this.controls = false;\n this.loop = false;\n this.muted = false;\n this.autoplay = false;\n\n // The keys are the event interfaces that are defined by `HTMLMediaElement` or `MediaSource` or `SourceBuffer`.\n // For example, `loadstart`, `loadedmetadata`, `loadeddata`, `canplay`, `canplaythrough`, `timeupdate`, `ended`,\n // `sourceopen`, `sourceended`, `sourceclose`, `updateend`, `error` ... etc\n this.listeners = {};\n }\n\n /**\n * This method gets `HTMLMediaElement` and selects media format. In addition, this method adds event listeners that are defined by `HTMLMediaElement`.\n * @param {HTMLAudioElement|HTMLVideoElement} media This argument is either `HTMLAudioElement` or `HTMLVideoElement`.\n * @param {Array.<string>|string} formats This argument is usable media format. For example, 'wav', 'ogg', 'webm', 'mp4' ...etc.\n * @param {object} listeners This argument is event handlers that are defined by `HTMLMediaElement`.\n * @param {boolean} autoplay This argument is in order to determine autoplay. The default value is `false`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n setup(media, formats, listeners, autoplay) {\n this.envelopegenerator.setGenerator(0);\n this.envelopegenerator.param({\n 'attack' : 0,\n 'decay' : 0.01,\n 'sustain' : 1,\n 'release' : 0.01\n });\n\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('media' in properties) {\n media = properties.media;\n }\n\n if ('formats' in properties) {\n formats = properties.formats;\n }\n\n if ('listeners' in properties) {\n listeners = properties.listeners;\n }\n\n if ('autoplay' in properties) {\n autoplay = properties.autoplay;\n }\n }\n\n let type = '';\n\n if (media instanceof HTMLAudioElement) {\n type = MediaModule.AUDIO;\n } else if (media instanceof HTMLVideoElement) {\n type = MediaModule.VIDEO;\n } else {\n return this;\n }\n\n this.media = media;\n\n if (!Array.isArray(formats)) {\n formats = [formats];\n }\n\n for (const format of formats) {\n const f = `${type}/${String(format).toLowerCase()}`;\n\n if (/^(?:maybe|probably)/.test(this.media.canPlayType(f))) {\n this.ext = format;\n break;\n }\n }\n\n if (Object.prototype.toString.call(listeners) === '[object Object]') {\n for (const k in listeners) {\n this.listeners[k.toLowerCase()] = (Object.prototype.toString.call(listeners[k]) === '[object Function]') ? listeners[k] : () => {};\n }\n }\n\n this.autoplay = Boolean(autoplay);\n\n // in the case of autoplay, `loadstart` event not fire\n if (this.autoplay && !(this.source instanceof MediaElementAudioSourceNode)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n\n if (this.autoplay && this.media.src) {\n this.context.resume()\n .then(() => {\n this.start(this.media.currentTime);\n })\n .catch(() => {\n throw new Error('Autoplay is failed');\n });\n }\n\n this.media.addEventListener('loadstart', event => {\n // To create the instance of `MediaElementAudioSourceNode` again causes error to occur\n if (!(this.source instanceof MediaElementAudioSourceNode)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n\n if ('loadstart' in this.listeners) {\n this.listeners.loadstart(event);\n }\n }, false);\n\n this.media.addEventListener('ended', event => {\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n if ('ended' in this.listeners) {\n this.listeners.ended(event);\n }\n }, false);\n\n for (const k in this.listeners) {\n this.media.addEventListener(k, event => {\n this.listeners[(event.type).toLowerCase()](event);\n }, false);\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|boolean|MediaModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let r;\n\n if (k === 'mastervolume') {\n r = super.param(k, value);\n }\n\n if (r !== undefined) {\n return r;\n }\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'playbackrate':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media.playbackRate : this.playbackRate;\n }\n\n v = parseFloat(value);\n min = 0.5; // for Chrome\n\n if (v >= min) {\n if (this.media instanceof HTMLMediaElement) {\n this.media.playbackRate = v;\n }\n\n this.playbackRate = v;\n\n const startTime = this.context.currentTime;\n const currentTime = this.param('currentTime');\n const duration = this.param('duration');\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / v)), true);\n }\n }\n\n break;\n case 'currenttime':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media.currentTime : 0;\n }\n\n if (this.media instanceof HTMLMediaElement) {\n v = parseFloat(value);\n min = 0;\n max = this.media.duration;\n\n if ((v >= min) && (v <= max)) {\n this.media.currentTime = v;\n\n const startTime = this.context.currentTime;\n const duration = this.param('duration');\n const playbackRate = this.param('playbackRate');\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - v) / playbackRate)), true);\n }\n }\n }\n\n break;\n case 'loop' :\n case 'muted' :\n case 'controls':\n if (value === undefined) {\n return (this.media instanceof HTMLMediaElement) ? this.media[k] : this[k];\n }\n\n if (this.media instanceof HTMLMediaElement) {\n this.media[k] = Boolean(value);\n }\n\n this[k] = Boolean(value);\n\n break;\n case 'width' :\n case 'height':\n if (value === undefined) {\n return (this.media instanceof HTMLVideoElement) ? this.media[k] : 0;\n }\n\n v = parseInt(value, 10);\n min = 0;\n\n if (v >= min) {\n if (this.media instanceof HTMLVideoElement) {\n this.media[k] = v;\n }\n }\n\n break;\n case 'duration':\n return this.media && this.media.duration ? this.media.duration : 0; // Getter only\n case 'channels':\n return (this.source instanceof MediaElementAudioSourceNode) ? this.source.channelCount : 0; // Getter only\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method prepares for playing the media anytime after loading the media resource.\n * @param {string} source This argument is path name or `Data URL` or `Object URL` for the media resource.\n * @param {string} mimeType This argument is required in the case of audio streaming.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n ready(source, mimeType) {\n const src = String(source);\n\n if (this.mse && (this.mse.readyState === 'open')) {\n this.mse.endOfStream();\n window.URL.revokeObjectURL(this.media.src);\n\n this.mse.removeEventListener('sourceopen', this.onSourceOpen, false);\n this.mse.removeEventListener('sourceended', this.onSourceEnded, false);\n this.mse.removeEventListener('sourceclose', this.onSourceClose, false);\n\n this.sb.removeEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sb.removeEventListener('error', this.onSourceBufferError, false);\n }\n\n try {\n if (mimeType) {\n // Audio Streaming\n if (!MediaSource || !MediaSource.isTypeSupported(mimeType)) {\n throw new Error('This Browser does not support `MediaSource` or MIME type');\n }\n\n this.media.removeAttribute('src');\n\n this.media.load();\n\n this.mse = new MediaSource();\n this.media.src = window.URL.createObjectURL(this.mse);\n this.mimeType = mimeType;\n this.file = src;\n\n this.onSourceOpen = this.onSourceOpen.bind(this);\n this.onSourceEnded = this.onSourceEnded.bind(this);\n this.onSourceClose = this.onSourceClose.bind(this);\n\n this.mse.addEventListener('sourceopen', this.onSourceOpen, false);\n this.mse.addEventListener('sourceended', this.onSourceEnded, false);\n this.mse.addEventListener('sourceclose', this.onSourceClose, false);\n } else if ((src.indexOf('data:') !== -1) || (src.indexOf('blob:') !== -1) || (this.ext === '')) {\n // `Data URL` or `Object URL` or Full path\n this.media.src = src;\n } else {\n // Path\n this.media.src = `${src}.${this.ext}`;\n }\n } catch (error) {\n throw new Error(error.message);\n }\n\n return this;\n }\n\n /**\n * This method starts media from the designated time.\n * @param {number} position This argument is the time that media is started at. The default value is 0.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n start(position, connects, processCallback) {\n if (this.source instanceof MediaElementAudioSourceNode) {\n // MediaElementAudioSourceNode (Input) -> GainNode (Envelope Generator) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor, connects);\n\n const promise = this.media.play();\n\n promise.then(() => {\n const startTime = this.context.currentTime;\n\n const pos = parseFloat(position);\n\n this.media.currentTime = ((pos >= 0) && (pos <= this.media.duration)) ? pos : 0;\n this.media.playbackRate = this.playbackRate;\n this.media.controls = this.controls;\n this.media.loop = this.loop;\n this.media.muted = this.muted;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in the case of audio streaming\n if (isFinite(this.media.duration)) {\n this.envelopegenerator.stop((startTime + ((this.media.duration - pos) / this.media.playbackRate)), true);\n }\n\n this.on(startTime);\n\n this.analyser.start('time');\n this.analyser.start('fft');\n\n const bufferSize = this.processor.bufferSize;\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.vocalcanceler.start(inputLs[i], inputRs[i]);\n outputRs[i] = this.vocalcanceler.start(inputRs[i], inputLs[i]);\n }\n };\n }\n }).catch(() => {\n this.stop(() => {\n if (this.autoplay) {\n this.media.muted = this.muted = true;\n this.media.volume = 0;\n }\n\n this.start(position, connects, processCallback);\n }, () => {\n });\n });\n }\n\n return this;\n }\n\n /**\n * This method stops media.\n * @param {function} successCallback This argument is invoked when `HTMLMediaElement#play` is successful.\n * @param {function} errorCallback This argument is invoked when `HTMLMediaElement#play` is failure.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n stop(successCallback, errorCallback) {\n if (this.source instanceof MediaElementAudioSourceNode) {\n // ref: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted\n this.media.play()\n .then(() => {\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback();\n }\n\n return Promise.resolve();\n })\n .catch(error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error);\n }\n\n return Promise.reject(error);\n });\n }\n\n return this;\n }\n\n /**\n * This method gets the instance of `MediaElementAudioSourceNode`.\n * @return {MediaElementAudioSourceNode}\n * @override\n */\n get() {\n return this.source;\n }\n\n /**\n * This method starts or stops media according to media state.\n * @param {number} position This argument is time that media is started at.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {MediaModule} This is returned for method chain.\n * @override\n */\n toggle(position, connects, processCallback) {\n if (this.media.paused) {\n this.start(position, connects, processCallback);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method determines whether the instance of `HTMLMediaElement` exists.\n * @return {boolean} If the instance of `HTMLMediaElement` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n isMedia() {\n return this.media instanceof HTMLMediaElement;\n }\n\n /**\n * This method determines whether the instance of `MediaElementAudioSourceNode` exists.\n * @return {boolean} If the instance of `MediaElementAudioSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n * @override\n */\n isSource() {\n return this.source instanceof MediaElementAudioSourceNode;\n }\n\n /**\n * This method determines whether the media is paused.\n * @return {boolean} If the media is paused or does not exists, this value is `true`. Otherwise, this value is `false`.\n * @override\n */\n isPaused() {\n return (this.media instanceof HTMLMediaElement) ? this.media.paused : true;\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceOpen(event) {\n this.sb = this.mse.addSourceBuffer(this.mimeType);\n\n this.sb.mode = 'sequence';\n\n this.onSourceBufferUpdateEnd = this.onSourceBufferUpdateEnd.bind(this);\n this.onSourceBufferError = this.onSourceBufferError.bind(this);\n\n this.sb.addEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sb.addEventListener('error', this.onSourceBufferError, false);\n\n if ('sourceopen' in this.listeners) {\n this.listeners.sourceopen(event);\n }\n\n const request = new Request(this.file);\n\n fetch(request)\n .then(response => {\n return response.arrayBuffer();\n })\n .then(data => {\n this.sb.appendBuffer(data);\n })\n .catch(error => {\n if ('error' in this.listeners) {\n this.listeners.error(event, error);\n }\n });\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceEnded(event) {\n if ('sourceended' in this.listeners) {\n this.listeners.sourceended(event);\n }\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceClose(event) {\n if ('sourceclose' in this.listeners) {\n this.listeners.sourceclose(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceBufferUpdateEnd(event) {\n if ('updateend' in this.listeners) {\n this.listeners.updateend(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is the instance of `Event`.\n */\n onSourceBufferError(event) {\n if ('error' in this.listeners) {\n this.listeners.error(event);\n }\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.media = {\n 'playbackrate' : this.playbackRate,\n 'vocalcanceler' : {\n 'depth' : this.vocalcanceler.param('depth')\n }\n };\n\n delete params.audio;\n\n return params;\n }\n\n /**\n * This method requests Picture In Picture (PIP).\n * @return {Promise} This is returned as `Promise`.\n */\n requestPictureInPicture() {\n if (!(this.media instanceof HTMLVideoElement)) {\n return Promise.reject();\n }\n\n if (!('pictureInPictureEnabled' in document)) {\n return Promise.reject();\n }\n\n if (!document.pictureInPictureEnabled) {\n return Promise.reject();\n }\n\n if (this.media.disablePictureInPicture) {\n return Promise.reject();\n }\n\n if (this.media.readyState === 0) {\n return Promise.reject();\n }\n\n if (this.media === document.pictureInPictureElement) {\n return Promise.reject();\n }\n\n return this.media.requestPictureInPicture();\n }\n\n /**\n * This method exits from Picture In Picture (PIP).\n * @return {Promise} This is returned as `Promise`.\n */\n exitPictureInPicture() {\n if (!(this.media instanceof HTMLVideoElement)) {\n return Promise.reject();\n }\n\n if (!('pictureInPictureEnabled' in document)) {\n return Promise.reject();\n }\n\n if (!document.pictureInPictureEnabled) {\n return Promise.reject();\n }\n\n if (this.media.disablePictureInPicture) {\n return Promise.reject();\n }\n\n if (this.media.readyState === 0) {\n return Promise.reject();\n }\n\n if (this.media !== document.pictureInPictureElement) {\n return Promise.reject();\n }\n\n return document.exitPictureInPicture();\n }\n\n /** @override */\n toString() {\n return '[MediaModule]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for Noise Gate.\n * @constructor\n */\nexport class NoiseGate {\n constructor() {\n this.level = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|NoiseGate} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'level':\n if (value === undefined) {\n return this.level;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.level = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method detects background noise and removes this.\n * @param {number} data This argument is amplitude (between -1 and 1).\n * @return {number} This is returned as 0 or the raw data.\n */\n start(data) {\n const d = Math.abs(parseFloat(data));\n\n // data : The amplitude is equal to argument.\n // 0 : Because signal is detected as background noise, the amplitude is 0.\n return (d > this.level) ? data : 0;\n }\n\n /** @override */\n toString() {\n return '[StreamModule NoiseGate]';\n }\n}\n","'use strict';\n\n/**\n * This private class defines properties for NoiseSuppressor.\n * @constructor\n */\nexport class NoiseSuppressor {\n /**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\n static FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n }\n\n /**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\n static IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n }\n\n /** @constructor */\n constructor() {\n this.threshold = 0;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|NoiseSuppressor} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n let v = null;\n let min = null;\n let max = null;\n\n switch (k) {\n case 'threshold':\n if (value === undefined) {\n return this.threshold;\n }\n\n v = parseFloat(value);\n min = 0;\n max = 1;\n\n if ((v >= min) && (v <= max)) {\n this.threshold = v;\n }\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method detects background noise and removes this.\n * @param {Float32Array} inputs This argument is the instance of `Float32Array` for `ScriptProcessorNode`.\n * @param {Float32Array} outpus This argument is the instance of `Float32Array` for `ScriptProcessorNode`.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n * @return {NoiseSuppressor} This is returned for method chain.\n */\n start(inputs, outputs, bufferSize) {\n if (this.threshold > 0) {\n const xreals = new Float32Array(inputs);\n const ximags = new Float32Array(bufferSize);\n\n const yreals = new Float32Array(bufferSize);\n const yimags = new Float32Array(bufferSize);\n\n const amplitudes = new Float32Array(bufferSize);\n const phases = new Float32Array(bufferSize);\n\n NoiseSuppressor.FFT(xreals, ximags, bufferSize);\n\n for (let k = 0; k < bufferSize; k++) {\n amplitudes[k] = Math.sqrt(Math.pow(xreals[k], 2) + Math.pow(ximags[k], 2));\n\n if ((xreals[k] !== 0) && (ximags[k] !== 0)) {\n phases[k] = Math.atan2(ximags[k], xreals[k]);\n }\n\n amplitudes[k] -= this.threshold;\n\n if (amplitudes[k] < 0) {\n amplitudes[k] = 0;\n }\n\n yreals[k] = amplitudes[k] * Math.cos(phases[k]);\n yimags[k] = amplitudes[k] * Math.sin(phases[k]);\n }\n\n NoiseSuppressor.IFFT(yreals, yimags, bufferSize);\n\n outputs.set(yreals);\n } else {\n outputs.set(inputs);\n }\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[StreamModule NoiseSuppressor]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { NoiseGate } from './NoiseGate';\nimport { NoiseSuppressor } from './NoiseSuppressor';\n\n/**\n * This class defines properties that processes sound data from WebRTC in Web Audio API.\n * @constructor\n * @extends {SoundModule}\n */\nexport class StreamModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.sources = []; /** @type {Array.<MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode>} */\n\n this.stream = null; // for the instance of `MediaStream`\n\n // for `navigator.mediaDevices.getUserMedia`\n this.constraints = {\n 'audio' : true,\n 'video' : false\n };\n\n this.callbacks = {\n 'stream' : () => {},\n 'error' : () => {}\n };\n\n this.each = false;\n this.output = true;\n\n this.isStop = true;\n\n this.noisegate = new NoiseGate();\n this.noisesuppressor = new NoiseSuppressor();\n }\n\n /**\n * This method sets up for using WebRTC.\n * @param {object} constraints This argument is the 1st argument for `getUserMedia`.\n * @param {function} streamCallback This argument is invoked on streaming.\n * @param {function} errorCallback This argument is invoked when error occurs on streaming.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n setup(constraints, streamCallback, errorCallback) {\n if (Object.prototype.toString.call(constraints) === '[object Object]') {\n this.constraints = constraints;\n }\n\n if (Object.prototype.toString.call(streamCallback) === '[object Function]') {\n this.callbacks.stream = streamCallback;\n }\n\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n this.callbacks.error = errorCallback;\n }\n\n return this;\n }\n\n /**\n * This method is getter or setter for parameters.\n * @param {string|object} key This argument is property name in the case of string type.\n * This argument is pair of property and value in the case of associative array.\n * @param {number|boolean} value This argument is the value of designated property. If this argument is omitted, This method is getter.\n * @return {number|boolean|StreamModule} This is returned as the value of designated property in the case of getter. Otherwise, this is returned for method chain.\n * @override\n */\n param(key, value) {\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n // Associative array\n for (const k in arguments[0]) {\n this.param(k, arguments[0][k]);\n }\n } else {\n const k = String(key).replace(/-/g, '').toLowerCase();\n\n const r = super.param(k, value);\n\n if (r !== undefined) {\n return r;\n }\n\n switch (k) {\n case 'each':\n if (value === undefined) {\n return this.each;\n }\n\n this.each = Boolean(value);\n\n break;\n case 'output':\n if (value === undefined) {\n return this.output;\n }\n\n this.output = Boolean(value);\n\n break;\n default:\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method opens devices or sets the instance of `MediaStream`.\n * @param {MediaStream} stream This argument is the instance of `MediaStream`.\n * @return {Promise} This is returned as `Promise` of `getUserMedia`.\n * @override\n */\n ready(stream) {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia || !window.MediaStream) {\n return Promise.reject('Cannot use WebRTC.');\n }\n\n this.isStop = false;\n\n if (stream instanceof MediaStream) {\n this.stream = stream;\n return Promise.resolve();\n }\n\n return navigator.mediaDevices.getUserMedia(this.constraints)\n .then(stream => {\n if (this.isStop) {\n return;\n }\n\n this.stream = stream;\n\n this.callbacks.stream(stream);\n }).catch(error => {\n this.callbacks.error(error);\n });\n }\n\n /**\n * This method starts streaming.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {Promise} This is returned as `Promise` of `getUserMedia`.\n * @override\n */\n start(connects, processCallback) {\n if (this.stream === null) {\n return this;\n }\n\n const bufferSize = this.processor.bufferSize;\n\n let runAnalyser = false;\n\n if (this.each) {\n // Get the instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (let i = 0, len = audioTracks.length; i < len; i++) {\n this.sources[i] = this.context.createMediaStreamTrackSource(audioTracks[i]);\n\n // MediaStreamTrackAudioSourceNode (Input) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.sources[i].connect(this.processor);\n this.connect(this.processor, connects);\n }\n } else {\n this.sources[0] = this.context.createMediaStreamSource(this.stream);\n\n // MediaStreamAudioSourceNode (Input) -> ScriptProcessorNode -> ... -> AudioDestinationNode (Output)\n this.sources[0].connect(this.processor);\n this.connect(this.processor, connects);\n }\n\n if (!this.output) {\n this.mastervolume.disconnect(0);\n\n // for analyser\n this.mastervolume.connect(this.analyser.input);\n\n // for recording\n this.mastervolume.connect(this.recorder.processor);\n this.recorder.processor.connect(this.context.destination);\n\n // for session\n this.mastervolume.connect(this.session.sender);\n this.session.sender.connect(this.context.destination);\n }\n\n this.on(this.context.currentTime);\n\n if (!runAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n runAnalyser = true;\n }\n\n if (Object.prototype.toString.call(processCallback) === '[object Function]') {\n this.processor.onaudioprocess = processCallback;\n } else {\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n for (let i = 0; i < bufferSize; i++) {\n outputLs[i] = this.noisegate.start(inputLs[i]);\n outputRs[i] = this.noisegate.start(inputRs[i]);\n }\n\n this.noisesuppressor.start(inputLs, outputLs, bufferSize);\n this.noisesuppressor.start(inputRs, outputRs, bufferSize);\n };\n }\n\n return this;\n }\n\n /**\n * This method stops streaming.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n stop() {\n this.sources.length = 0;\n\n this.off(this.context.currentTime, true);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n\n this.isStop = true;\n\n return this;\n }\n\n /**\n * This method gets the instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode`.\n * @param {number} index This argument is required in the case of designating track.\n * @return {MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode|Array.<MediaStreamTrackAudioSourceNode>}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /**\n * This method gets the instance of `MediaStream`.\n * @return {MediaStream}\n * @override\n */\n getStream() {\n return this.stream;\n }\n\n /**\n * This method starts or stops streaming according to current state.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {StreamModule} This is returned for method chain.\n */\n toggle(connects, processCallback) {\n if (this.isStreaming()) {\n this.stop();\n } else {\n this.start(connects, processCallback);\n }\n\n return this;\n }\n\n /**\n * This method stops microphone and camera by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clear() {\n this.stop();\n\n this.clearAudio();\n this.clearVideo();\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clearAudio() {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get the instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (const audioTrack of audioTracks) {\n audioTrack.stop();\n }\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping the instances of `MediaStreamTrack`.\n * @return {StreamModule} This is returned for method chain.\n * @override\n */\n clearVideo() {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get the instance of `MediaStreamTrack` for video\n const videoTracks = this.stream.getVideoTracks();\n\n for (const videoTrack of videoTracks) {\n videoTrack.stop();\n }\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method gets available devices as array that contains the instances of `MediaDeviceInfo`.\n * @return {Promise} This is returned as `Promise` of `enumerateDevices`.\n */\n devices() {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return Promise.reject('No devices.');\n }\n\n return navigator.mediaDevices.enumerateDevices();\n }\n\n /**\n * This method determines whether streaming is active.\n * @return {boolean} If streaming is active, this value is `true`. Otherwise, this value is `false`.\n */\n isStreaming() {\n return !this.isStop;\n }\n\n /** @override */\n params() {\n const params = super.params();\n\n params.stream = {\n 'output' : this.output,\n 'noisegate' : { 'level' : this.noisegate.param('level') },\n 'noisesuppressor' : { 'threshold' : this.noisesuppressor.param('threshold') }\n };\n\n return params;\n }\n\n /** @override */\n toString() {\n return '[StreamModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { AudioModule } from '../AudioModule';\nimport { MediaModule } from '../MediaModule';\nimport { StreamModule } from '../StreamModule';\n\n/**\n * This class defines properties for mixing sound sources that is defined in this library.\n * @constructor\n * @extends {SoundModule}\n */\nexport class MixerModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n /** @type {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>} */\n this.sources = [];\n\n this.isAnalyser = false;\n }\n\n /**\n * This method mixes sound source.\n * @param {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>} sources This argument is the array of sound source that is defined by this library.\n * @return {MixerModule} This is returned for method chain.\n */\n mix(sources) {\n if (!Array.isArray(sources)) {\n sources = [sources];\n }\n\n this.sources = sources;\n\n for (const source of this.sources) {\n if (!((source instanceof OscillatorModule) || (source instanceof OneshotModule) || (source instanceof AudioModule) || (source instanceof MediaModule) || (source instanceof StreamModule))) {\n return this;\n }\n\n const stopTime = this.context.currentTime;\n\n this.off(stopTime, false);\n\n source.analyser.stop('time');\n source.analyser.stop('fft');\n source.isAnalyser = false;\n\n source.recorder.stop();\n source.session.close();\n\n // ScriptProcessorNode (each sound source) -> ScriptProcessorNode (Mix sound sources)\n source.processor.disconnect(0);\n source.processor.connect(this.processor);\n }\n\n // (... ->) ScriptProcessorNode (Mix sound sources) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n\n const startTime = this.context.currentTime;\n\n this.on(startTime);\n\n if (!this.isAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.isAnalyser = true;\n }\n\n this.processor.onaudioprocess = event => {\n const inputLs = event.inputBuffer.getChannelData(0);\n const inputRs = event.inputBuffer.getChannelData(1);\n const outputLs = event.outputBuffer.getChannelData(0);\n const outputRs = event.outputBuffer.getChannelData(1);\n\n // Stop ?\n let isStop = false;\n\n for (const source of sources) {\n if ((source instanceof OscillatorModule) && source.envelopegenerator.isStop()) {\n isStop = true;\n } else if ((source instanceof OneshotModule) && source.isStop) {\n isStop = true;\n } else if ((source instanceof AudioModule) && source.paused) {\n isStop = true;\n } else if ((source instanceof MediaModule) && source.media.paused) {\n isStop = true;\n } else if ((source instanceof StreamModule) && source.isStop) {\n isStop = true;\n }\n }\n\n if (isStop) {\n const stopTime = this.context.currentTime;\n\n this.on(stopTime, true);\n\n this.analyser.stop('time');\n this.analyser.stop('fft');\n this.isAnalyser = false;\n\n // Stop `onaudioprocess` event\n this.processor.disconnect(0);\n this.processor.onaudioprocess = null;\n } else {\n outputLs.set(inputLs);\n outputRs.set(inputRs);\n }\n };\n\n return this;\n }\n\n /**\n * This method gets the instance of sound source that is mixed in this class.\n * @param {number} index This argument is required in the case of designating sound source.\n * @return {Array.<OscillatorModule>|Array.<OneshotModule>|Array.<AudioModule>|Array.<MediaModule>|Array.<StreamModule>|OscillatorModule|OneshotModule|AudioModule|MediaModule|StreamModule}\n * @override\n */\n get(index) {\n const i = parseInt(index, 10);\n\n return ((i >= 0) && (i < this.sources.length)) ? this.sources[i] : this.sources;\n }\n\n /** @override */\n toString() {\n return '[MixerModule]';\n }\n}\n","'use strict';\n\nimport { SoundModule } from '../SoundModule';\n\nexport class ProcessorModule extends SoundModule {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n * @param {number} bufferSize This argument is buffer size for `ScriptProcessorNode`.\n */\n constructor(context, bufferSize) {\n super(context, bufferSize);\n\n this.envelopegenerator.setGenerator(0);\n\n this.processor = null;\n this.name = '';\n this.options = {};\n this.moduleURL = '';\n this.promise = null;\n this.map = null; // Polyfill for `AudioParamMap`\n\n this.runAnalyser = false;\n }\n\n /**\n * This method sets registered processor and options for `AudioWorkletNode` constructor.\n * @param {string} name This argument is the name of the `AudioWorkletProcessor` this node will be based on.\n * @param {object} options This argument is an object based on the `AudioWorkletNodeOptions` dictionary.\n * @return {ProcessorModule} This is returned for method chain.\n * @override\n */\n setup(name, options) {\n this.name = String(name);\n\n if (Object.prototype.toString.call(options) === '[object Object]') {\n this.options = options;\n }\n\n if (!window.AudioWorkletNode) {\n // Polyfill\n this.processor = this.context.createScriptProcessor(this.bufferSize, SoundModule.NUMBER_OF_INPUTS, SoundModule.NUMBER_OF_OUTPUTS);\n this.map = new Map();\n }\n\n return this;\n }\n\n /**\n * This method adds module for worklet and creates the instance of `AudioWorkletNode`.\n * @param {string} moduleURL This argument is the string containing the URL of a JavaScript file with the module to add.\n * @param {object} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise} This is returned as `Promise` of `addModule`.\n * @override\n */\n ready(moduleURL, options) {\n if (!window.AudioWorkletNode) {\n return Promise.reject('Cannot use AudioWorklet');\n }\n\n this.moduleURL = String(moduleURL);\n\n if (Object.prototype.toString.call(options) === '[object Object]') {\n this.promise = this.context.audioWorklet.addModule(this.moduleURL, options);\n } else {\n this.promise = this.context.audioWorklet.addModule(this.moduleURL);\n }\n\n return this.promise\n .then(() => {\n if (Object.keys(this.options).length > 0) {\n this.processor = new AudioWorkletNode(this.context, this.name, this.options);\n } else {\n this.processor = new AudioWorkletNode(this.context, this.name);\n }\n });\n }\n\n /**\n * This method starts sound by connecting to `AudioDestinationNode`.\n * @param {function} processCallback This argument is in order to set `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @param {Array.<Effector>} connects This argument is the array for changing the default connection.\n * @return {ProcessorModule} This is returned as method chain.\n * @override\n */\n start(processCallback, connects) {\n const startTime = this.context.currentTime;\n\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n\n if (this.processor.onaudioprocess instanceof ScriptProcessorNode) {\n this.processor.onaudioprocess = null;\n }\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(this.envelopegenerator.getGenerator(0), connects);\n\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runAnalyser) {\n this.analyser.start('time');\n this.analyser.start('fft');\n this.runAnalyser = true;\n }\n\n this.on(startTime);\n\n if ((this.processor instanceof ScriptProcessorNode) && (Object.prototype.toString.call(processCallback) === '[object Function]')) {\n this.processor.onaudioprocess = processCallback;\n }\n\n return this;\n }\n\n /**\n * This method stops sound by disconnecting to `AudioDestinationNode`.\n * @param {function} processCallback This argument is in order to change `onaudioprocess` event handler in the instance of `ScriptProcessorNode`.\n * @return {ProcessorModule} This is returned for method chain.\n * @override\n */\n stop(processCallback) {\n const stopTime = this.context.currentTime;\n\n this.processor.disconnect(0);\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n if ((this.processor instanceof ScriptProcessorNode) && (Object.prototype.toString.call(processCallback) === '[object Function]')) {\n this.processor.onaudioprocess = processCallback;\n }\n\n return this;\n }\n\n /**\n * This method sends a message from the `MessagePort` of `AudioWorkletNode`.\n * @param {any} data This argument is sent as any data.\n * @return {ProcessorModule} This is returned for method chain.\n */\n postMessage(data) {\n if (this.processor instanceof AudioWorkletNode) {\n this.processor.port.postMessage(data);\n }\n\n return this;\n }\n\n /**\n * This method sets the event handler that is invoked when the port receives a message.\n * @param {function} This argument is invoked when the port receives a message.\n * @return {ProcessorModule} This is returned for method chain.\n */\n onMessage(callback) {\n if (this.processor instanceof AudioWorkletNode) {\n if ((Object.prototype.toString.call(callback) === '[object Function]') || (callback === null)) {\n this.processor.port.onmessage = callback;\n }\n }\n\n return this;\n }\n\n /**\n * This method sets the event handler that is invoked when it receives a message that cannot be deserialized.\n * @param {function} This argument is invoked when it receives a message that cannot be deserialized.\n * @return {ProcessorModule} This is returned for method chain.\n */\n onMessageError(callback) {\n if (this.processor instanceof AudioWorkletNode) {\n if ((Object.prototype.toString.call(callback) === '[object Function]') || (callback === null)) {\n this.processor.port.onmessageerror = callback;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets object that is accessed as a `AudioParamMap`.\n * @return {AudioParamMap|Map} This is returned as `AudioParamMap` (or empty `Map`).\n */\n map() {\n if (this.processor instanceof AudioWorkletNode) {\n return this.processor.parameters;\n }\n\n return this.map;\n }\n\n /**\n * This method gets the instance of `AudioParam` that is defined by `AudioParamDescriptor`.\n * @param {string} This argument is the key for getting as `AudioParam`.\n * @return {AudioParam} This is returned as `AudioParam`.\n */\n param(key) {\n if (this.processor instanceof AudioWorkletNode) {\n return this.processor.parameters.get(key);\n }\n\n return null;\n }\n\n /**\n * This method gets the instance of `AudioWorkletNode` (or `ScriptProcessorNode`).\n * @return {AudioWorkletNode|ScriptProcessorNode}\n * @override\n */\n get() {\n return this.processor;\n }\n\n /** @override */\n toString() {\n return '[ProcessorModule]';\n }\n}\n","'use strict';\n\n/**\n * This class defines properties for using Web MIDI API.\n * @constructor\n */\nexport class MIDI {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.midiAccess = null; // for the instance of `MIDIAccess`\n this.inputs = []; // for the instances of `MIDIInput`\n this.outputs = []; // for the instances of `MIDIOutput`\n }\n\n /**\n * This method invokes `requestMIDIAccess` and gets objects for using Web MIDI API.\n * @param {boolean} sysex This argument is in order to select whether using system exclusive message.\n * @param {function} successCallback This argument is invoked when `requestMIDIAccess` succeeds.\n * @param {function} errorCallback This argument is invoked when `requestMIDIAccess` fails.\n * @return {MIDI} This is returned for method chain.\n */\n setup(sysex, successCallback, errorCallback) {\n if (!navigator.requestMIDIAccess) {\n throw new Error('Cannot use Web MIDI API.');\n }\n\n navigator.requestMIDIAccess({ sysex : Boolean(sysex) }).then(midiAccess => {\n this.midiAccess = midiAccess;\n\n if (Object.prototype.toString.call(midiAccess) === '[object Function]') {\n // Legacy Chrome\n this.inputs = midiAccess.inputs();\n this.outputs = midiAccess.outputs();\n } else {\n // Chrome 39 and later\n const inputIterator = midiAccess.inputs.values();\n const outputIterator = midiAccess.outputs.values();\n\n for (let i = inputIterator.next(); !i.done; i = inputIterator.next()) {\n this.inputs.push(i.value);\n }\n\n for (let o = outputIterator.next(); !o.done; o = outputIterator.next()) {\n this.outputs.push(o.value);\n }\n }\n\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n successCallback(this.midiAccess, this.inputs, this.outputs);\n }\n }).catch(error => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(error);\n }\n });\n\n return this;\n }\n\n /**\n * This method gets the instance of `MIDIAccess`.\n * @return {MIDIAccess}\n */\n get() {\n return this.midiAccess;\n }\n\n /** @override */\n toString() {\n return '[MIDI]';\n }\n}\n","'use strict';\n\n/**\n * MML characters are corresponds to tokens by this map.\n * Namely, this map is definitions of MML Tokens.\n */\nexport const TokenMap = new Map([\n ['T', 'TEMPO'],\n ['O', 'OCTAVE'],\n ['C', 'NOTE'],\n ['D', 'NOTE'],\n ['E', 'NOTE'],\n ['F', 'NOTE'],\n ['G', 'NOTE'],\n ['A', 'NOTE'],\n ['B', 'NOTE'],\n ['+', 'NOTE'],\n ['-', 'NOTE'],\n ['#', 'NOTE'],\n ['R', 'REST'],\n ['0', 'NUMBER'],\n ['1', 'NUMBER'],\n ['2', 'NUMBER'],\n ['3', 'NUMBER'],\n ['4', 'NUMBER'],\n ['5', 'NUMBER'],\n ['6', 'NUMBER'],\n ['7', 'NUMBER'],\n ['8', 'NUMBER'],\n ['9', 'NUMBER'],\n ['.', 'NUMBER'],\n ['&', 'TIE'],\n [' ', 'SPACE'],\n [undefined, 'EOS']\n]);\n\n/**\n * This is enumeration types for MML Tokens.\n */\nexport const TokenTypes = {\n 'TEMPO' : 1,\n 'OCTAVE' : 2,\n 'NOTE' : 3,\n 'REST' : 4,\n 'NUMBER' : 5,\n 'TIE' : 6,\n 'SPACE' : 7,\n 'EOS' : 8,\n 'UNKNOWN': 9\n};\n\n/**\n * This class has token type, token data and token value if token is number.\n * @constructor\n */\nexport class Token {\n /**\n * @param {TokenTypes} type This argument is the one of enumeration values that is defined by `TokenTypes`.\n * @param {string} token This argument is a string that constructs of token.\n */\n constructor(type, token) {\n this.type = type;\n this.token = token;\n this.value = parseInt(token, 10);\n }\n\n /**\n * This method is getter for token type.\n */\n getType() {\n return this.type || null;\n }\n\n /**\n * This method is getter for token.\n */\n getToken() {\n return this.token;\n }\n\n /**\n * This method is getter for token value if token is number.\n */\n getValue() {\n return isNaN(this.value) ? null : this.value;\n }\n}\n","'use strict';\n\nimport { TokenMap, TokenTypes, Token } from './Token';\n\n/**\n * This class is Tokenization for MML (Music Macro Language).\n * @constructor\n */\nexport class Tokenizer {\n /**\n * @param {string} mml This argument is MML string.\n */\n constructor(mml) {\n if (typeof mml === 'string') {\n // `reverse` for getting token by `pop`\n this.tokens = mml.trim().toUpperCase().split('').reverse();\n } else {\n this.tokens = [];\n }\n\n this.notes = [];\n this.numbers = [];\n }\n\n /**\n * This method executes tokenization from MML.\n * @return {Token} This is returned as the instance of `Token`.\n */\n get() {\n let token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.SPACE) {\n token = this.tokens.pop();\n }\n\n if (TokenTypes[TokenMap.get(token)] === TokenTypes.EOS) {\n return new Token(TokenTypes.EOS, token);\n }\n\n this.notes.length = 0;\n this.numbers.length = 0;\n\n switch (TokenTypes[TokenMap.get(token)]) {\n case TokenTypes.TEMPO:\n return new Token(TokenTypes.TEMPO, token);\n case TokenTypes.OCTAVE:\n return new Token(TokenTypes.OCTAVE, token);\n case TokenTypes.NOTE:\n this.notes.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.NOTE) {\n this.notes.push(token);\n\n token = this.tokens.pop();\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(TokenTypes.NOTE, this.notes.join(''));\n case TokenTypes.REST:\n return new Token(TokenTypes.REST, token);\n case TokenTypes.NUMBER:\n this.numbers.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n while (TokenTypes[TokenMap.get(token)] === TokenTypes.NUMBER) {\n this.numbers.push(token);\n\n token = this.tokens.pop();\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(TokenTypes.NUMBER, this.numbers.join(''));\n case TokenTypes.TIE:\n return new Token(TokenTypes.TIE, token);\n default:\n return new Token(TokenTypes.UNKNOWN, token);\n }\n }\n}\n","'use strict';\n\n/**\n * This class is structure for Tree Construction.\n * @constructor\n */\nexport class Tree {\n static indent = 0;\n\n /**\n * @param {Token} operator This argument is the instance of `Token` as Tree Node.\n * @param {Tree} left This argument is the instance of `Tree` as left partial tree.\n * @param {Tree} right This argument is the instance of `Tree` as right partial tree.\n */\n constructor(operator, left, right) {\n this.operator = operator;\n this.left = left;\n this.right = right;\n }\n\n /**\n * This method concatenates partial tree as right partial tree.\n * @param {Token} operator This argument is the instance of `Token` as Tree Node.\n */\n concat(node) {\n this.right = node;\n }\n\n /**\n * This method is getter for operator.\n */\n getOperator() {\n return this.operator;\n }\n\n /**\n * This method is getter for left partial tree\n */\n getLeft() {\n return this.left;\n }\n\n /**\n * This method is getter for right partial tree\n */\n getRight() {\n return this.right;\n }\n\n /** @override */\n toString() {\n let space = '';\n\n for (let i = 0; i < Tree.indent; i++) {\n space += ' ';\n }\n\n Tree.indent++;\n\n // Return syntax tree string\n return `\n ${space} ${this.operator.getToken()}\n ${space} /\\\\\n ${space}${this.left !== null ? this.left.getOperator().getToken() : ''}\n ${space}${((this.right !== null) && (this.right.getOperator().getToken() !== undefined)) ? this.toString.call(this.right) : 'EOS'}\n `;\n }\n}\n","'use strict';\n\nimport { TokenTypes } from './Token';\nimport { Tree } from './Tree';\n\n/**\n * This class is Tree Construction (syntax tree) for MML (Music Macro Language).\n * @constructor\n */\nexport class TreeConstructor {\n /**\n * @param {Tokenizer} tokenizer This argument is the instance of `Tokenizer`.\n */\n constructor(tokenizer) {\n this.tokenizer = tokenizer; // The instance of `Tokenizer`\n this.syntaxTree = []; /** @type Array.<Tree> */\n }\n\n /**\n * This method executes tree construction (parsing) from tokens.\n * @return {Array.<Tree>} This is returned as syntax tree.\n */\n parse() {\n let token = this.tokenizer.get();\n let nextToken = this.tokenizer.get();\n\n while (true) {\n switch (token.getType()) {\n case TokenTypes.TEMPO:\n if (nextToken.getType() === TokenTypes.NUMBER) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n // /T\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TEMPO, token);\n case TokenTypes.OCTAVE:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /O\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.OCTAVE, token);\n case TokenTypes.NOTE:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /(?:[CDEFGABR][#+-]?)+\\d+\\.?/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.NOTE, token);\n case TokenTypes.REST:\n if ((this.syntaxTree.length > 0) && (nextToken.getType() === TokenTypes.NUMBER)) {\n const left = new Tree(nextToken, null, null); // Leaf\n const tree = new Tree(token, left, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /R\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.REST, token);\n case TokenTypes.NUMBER:\n // Noop\n break;\n case TokenTypes.TIE:\n if (this.syntaxTree.length > 0) {\n const tree = new Tree(token, null, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n // /&/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TIE, token);\n case TokenTypes.EOS:\n if (this.syntaxTree.length > 0) {\n const tree = new Tree(token, null, null);\n\n const parentNode = this.syntaxTree[this.syntaxTree.length - 1];\n\n parentNode.concat(tree);\n\n this.syntaxTree.push(tree);\n } else {\n const tree = new Tree(token, null, null);\n\n this.syntaxTree.push(tree);\n }\n\n return this.syntaxTree;\n default:\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, token);\n }\n\n token = nextToken;\n nextToken = this.tokenizer.get();\n }\n }\n\n /**\n * This method releases the memory that stack has.\n */\n free() {\n this.syntaxTree.length = 0;\n }\n}\n\n/**\n * This class is error class for MML syntax error (extends `Error`).\n * @constructor\n */\nexport class MMLSyntaxError extends Error {\n static ERRORS = {\n TEMPO : 'tempo',\n OCTAVE : 'octave',\n NOTE : 'note',\n REST : 'rest',\n TIE : 'tie',\n UNKNOWN : 'unknown'\n };\n\n /**\n * @param {string} error This argument is one of 'tempo', 'octave', 'note', 'rest', 'tie', 'unknown'.\n * @param {Token} token This argument is the instance of `Token` that error occurs in.\n */\n constructor(error, token) {\n super(error);\n\n this.token = token;\n this.error = error;\n }\n}\n","'use strict';\n\n/**\n * This class is the entity for sequence that has musical notes.\n * @constructor\n */\nexport class Sequence {\n /**\n * @param {string} note This argument is the string that corresponds to MML token.\n * @param {Array.<number>} indexes This argument is the array that contains the indexes that corresponds to the 12 equal temperament.\n * @param {Array.<number>} frequencies This argument is the array that contains the frequencies.\n * @param {number} start This argument is the start time.\n * @param {number} stop This argument is the stop time.\n * @param {number} duration This argument is the duration.\n */\n constructor(note, indexes, frequencies, start, stop, duration) {\n this.note = note;\n this.indexes = indexes;\n this.frequencies = frequencies;\n this.start = start;\n this.stop = stop;\n this.duration = duration;\n }\n\n /**\n * This method concatenates sequence in the case of tie.\n * @param {Sequence} sequence This argument is the instance of `Sequence`.\n */\n concat(sequence) {\n const s = sequence.toPlainObject();\n\n this.note += `&${s.note}`;\n this.duration += s.duration;\n\n this.stop = this.start + this.duration;\n }\n\n /**\n * This method converts the values that the instance of `Sequence` has to plain object and returns it.\n * @return {object} This is returned as the plain object that has musical notes.\n */\n toPlainObject() {\n return {\n 'note' : this.note,\n 'indexes' : this.indexes,\n 'frequencies' : this.frequencies,\n 'start' : this.start,\n 'stop' : this.stop,\n 'duration' : this.duration\n };\n }\n}\n","'use strict';\n\nimport { TokenTypes, Token } from './Token';\nimport { Tree } from './Tree';\nimport { Sequence } from './Sequence';\nimport { MMLSyntaxError } from './TreeConstructor';\n\n/**\n * This class converts syntax tree to the array that contains musical notes.\n * @constructor\n */\nexport class Sequencer {\n static FREQUENCY_RATIO = Math.pow(2, (1 / 12)); // about 1.059463\n static MIN_A = 27.5;\n static EQUAL_TEMPERAMENT = 12;\n static QUARTER_NOTE = 4;\n\n static C = 'C';\n static D = 'D';\n static E = 'E';\n static F = 'F';\n static G = 'G';\n static A = 'A';\n static B = 'B';\n static R = 'R';\n\n static SHARP = '#';\n static HALF_UP = '+';\n static HALF_DOWN = '-';\n\n static DOT = '.';\n\n /**\n * This class (static) method computes index by octave and pitch name.\n * @param {number} octave This argument is octave.\n * @param {string} pitchname This argument is pitch name.\n * @return {number} This is returned as index that is computed by octave and pitch name.\n */\n static computeIndex(octave, pitchname) {\n let index = 0;\n\n switch (pitchname) {\n case Sequencer.C:\n index = 3;\n break;\n case Sequencer.D:\n index = 5;\n break;\n case Sequencer.E:\n index = 7;\n break;\n case Sequencer.F:\n index = 8;\n break;\n case Sequencer.G:\n index = 10;\n break;\n case Sequencer.A:\n index = 12;\n break;\n case Sequencer.B:\n index = 14;\n break;\n case Sequencer.R:\n return -1;\n default:\n // eslint-disable-next-line no-console\n console.assert();\n break;\n }\n\n const computedIndex = (Sequencer.EQUAL_TEMPERAMENT * (octave - 1)) + index;\n\n return (computedIndex >= 0) ? computedIndex : -1;\n }\n\n /**\n * This class (static) method computes frequency from the index that corresponds to the 12 equal temperament.\n * @param {number} index This argument is the index that corresponds to the 12 equal temperament.\n * For example, This value is between 0 and 88 in the case of piano.\n * @return {number} This is returned as frequency.\n */\n static computeFrequency(index) {\n return (index >= 0) ? (Sequencer.MIN_A * Math.pow(Sequencer.FREQUENCY_RATIO, index)) : 0;\n }\n\n /**\n * @param {TreeConstructor} treeConstructor This argument is the instance of `TreeConstructor`.\n */\n constructor(treeConstructor) {\n this.sequences = []; /** @type {Array.<Sequence>} */\n\n this.treeConstructor = treeConstructor;\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n }\n\n /**\n * This method calculates pitch and music time from Parse Tree.\n * @return {Array.<object>|MMLSyntaxError} This is returned as array that contains sequence objects for playing the MML.\n * If error occurs, this is returned as `MMLSyntaxError`.\n */\n get() {\n const trees = this.treeConstructor.parse();\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n\n let tree = trees[0];\n\n while (tree !== null) {\n if (!(tree instanceof Tree)) {\n if (tree instanceof MMLSyntaxError) {\n return tree;\n }\n\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, null);\n }\n\n const operator = tree.getOperator();\n const type = operator.getType();\n\n const left = tree.getLeft();\n const right = tree.getRight();\n\n const value = left !== null ? left.getOperator().getValue() : -1;\n\n switch (type) {\n case TokenTypes.TEMPO:\n if (value <= 0) {\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.TEMPO, operator.getToken());\n }\n\n this.timeOf4note = 60 / value;\n\n tree = right;\n break;\n case TokenTypes.OCTAVE:\n if (value < 0) {\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.OCTAVE, operator.getToken());\n }\n\n this.octave = value;\n\n tree = right;\n break;\n case TokenTypes.NOTE:\n case TokenTypes.REST:\n case TokenTypes.TIE :\n const r = this.push(type === TokenTypes.TIE ? right : tree);\n\n if (r instanceof MMLSyntaxError) {\n return r;\n }\n\n if (type === TokenTypes.TIE) {\n this.concat();\n\n tree = right.getRight();\n } else {\n tree = right;\n }\n\n break;\n case TokenTypes.EOS:\n tree = right;\n break;\n default:\n return new MMLSyntaxError(MMLSyntaxError.ERRORS.UNKNOWN, null);\n }\n }\n\n // Release Memory for improving MML performance\n this.treeConstructor.free();\n\n return this.sequences;\n }\n\n /**\n * This method constructs syntax tree.\n * @param {Tree} tree This argument is the instance of `Tree` that is added to syntax tree.\n */\n push(tree) {\n const left = tree.getLeft();\n const right = tree.getRight();\n\n // Not leaf\n if ((left === null) || (right === null)) {\n return;\n }\n\n // Not leaf\n const leftToken = left.getOperator();\n const rightToken = right.getOperator();\n\n if (!(leftToken instanceof Token) && !(rightToken instanceof Token)) {\n // Traverse tree by recursive call\n this.push(left);\n this.push(right);\n return;\n }\n\n // Leaf\n const token = tree.getOperator().getToken();\n const value = leftToken.getValue();\n const digits = leftToken.getToken();\n\n const indexes = [];\n const frequencies = [];\n\n for (let i = 0, len = token.length; i < len; i++) {\n const note = token.charAt(i);\n\n let index = Sequencer.computeIndex(this.octave, note);\n\n // Sharp or Flat (Half up or Half down) ?\n switch (token.charAt(i + 1)) {\n case Sequencer.HALF_UP:\n case Sequencer.SHARP :\n index++;\n i++;\n break;\n case Sequencer.HALF_DOWN:\n index--;\n i++;\n break;\n default:\n // Normal (Natural)\n break;\n }\n\n // in the case of chord\n if (index >= indexes[0]) {\n index -= Sequencer.EQUAL_TEMPERAMENT;\n }\n\n if ((index !== -1) && (index < 0)) {\n // eslint-disable-next-line no-console\n console.assert();\n return;\n }\n\n indexes.push(index);\n }\n\n for (const index of indexes) {\n const frequency = Sequencer.computeFrequency(index);\n\n // Validation\n if (frequency < 0) {\n // eslint-disable-next-line no-console\n console.assert();\n return;\n }\n\n frequencies.push(frequency);\n }\n\n let duration = 0;\n\n switch (value) {\n case 1:\n case 2:\n case 4:\n case 8:\n case 16:\n case 32:\n case 64:\n case 128:\n case 256:\n const numberOf4note = Sequencer.QUARTER_NOTE / value;\n\n // Dotted note ?\n if (digits.includes(Sequencer.DOT)) {\n duration += 1.5 * (numberOf4note * this.timeOf4note);\n } else {\n duration += numberOf4note * this.timeOf4note;\n }\n\n break;\n case 6:\n // Triplet of half note\n duration += (2 * this.timeOf4note) / 3;\n break;\n case 12:\n // Triplet of quarter note\n duration += this.timeOf4note / 3;\n break;\n case 18:\n // Nonuplet of half note\n duration += (2 * this.timeOf4note) / 9;\n break;\n case 24:\n // Triplet of 8th note\n duration += (0.5 * this.timeOf4note) / 3;\n break;\n case 36:\n // Nonuplet of quarter note\n duration += this.timeOf4note / 9;\n break;\n case 48:\n // Triplet of 16th note\n duration += (0.25 * this.timeOf4note) / 3;\n break;\n case 72:\n // Nonuplet of 8th note\n duration += (0.5 * this.timeOf4note) / 9;\n break;\n case 96:\n // Triplet of 32th note\n duration += (0.125 * this.timeOf4note) / 3;\n break;\n case 144:\n // Nonuplet of 16th note\n duration += (0.25 * this.timeOf4note) / 9;\n break;\n case 192:\n // Triplet of 64th note\n duration += (0.0625 * this.timeOf4note) / 3;\n break;\n default:\n // eslint-disable-next-line no-console\n console.assert();\n break;\n }\n\n this.sequences.push(new Sequence(\n `${token}${digits}`,\n indexes,\n frequencies,\n this.currentTime,\n (this.currentTime + duration),\n duration\n ));\n\n this.currentTime += duration;\n }\n\n /**\n * This method concats previous note and previous duration and current note and current duration in the case of tie.\n */\n concat() {\n const current = this.sequences.pop();\n const previous = this.sequences.pop();\n\n previous.concat(current);\n\n this.sequences.push(previous);\n }\n}\n","'use strict';\n\nimport { Tokenizer } from './Tokenizer';\nimport { TreeConstructor, MMLSyntaxError } from './TreeConstructor';\nimport { Sequencer } from './Sequencer';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { NoiseModule } from '../NoiseModule';\n\n/**\n * This class parses, starts and stops MML as each MML part.\n * @constructor\n */\nexport class Part {\n /**\n * @param {OscillatorModule|OneshotModule|NoiseModule} source This argument is in order to select sound source.\n * @param {string} mml This argument is MML string.\n * @param {number} offset This argument is in order to correct the index of one-shot audio.\n * @param {object.<string, function>} callbacks This argument is callback functions.\n * @param {number} offset This argument is in order to correct the index of one-shot audio.\n */\n constructor(source, mml, callbacks, offset) {\n this.source = null; /** @type {OscillatorModule|OneshotModule|NoiseModule} */\n this.mml = '';\n this.previous = null; /** @type {Sequence} */\n this.timerid = null; /** @type {number} */\n this.currentIndex = 0; /** @type {number} */\n this.currentPosition = 0; /** @type {number} */\n this.offset = 0;\n\n if ((source instanceof OscillatorModule) || (source instanceof OneshotModule) || (source instanceof NoiseModule)) {\n this.source = source;\n }\n\n if (typeof mml === 'string') {\n this.mml = mml;\n }\n\n this.callbacks = {\n 'start' : () => {},\n 'stop' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n\n if (Object.prototype.toString.call(callbacks) === '[object Object]') {\n Object.keys(callbacks).forEach(key => {\n const k = key.toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(callbacks[k]) === '[object Function]') {\n this.callbacks[k] = callbacks[k];\n }\n }\n });\n }\n\n const o = parseInt(offset, 10);\n\n if (!isNaN(o) && (o >= 0)) {\n this.offset = o;\n }\n\n const tokenizer = new Tokenizer(mml);\n const treeConstructor = new TreeConstructor(tokenizer);\n const sequencer = new Sequencer(treeConstructor);\n\n this.sequences = sequencer.get();\n\n if ((this.sequences instanceof MMLSyntaxError) && this.callbacks.error) {\n this.callbacks.error(this.sequences);\n }\n }\n\n /**\n * This method starts MML. Moreover, this method schedules next sequence.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Effector>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n */\n start(highlight, connects) {\n if (!this.sequences[this.currentIndex]) {\n this.stop();\n this.callbacks.ended();\n\n return;\n }\n\n const sequence = this.sequences[this.currentIndex++].toPlainObject();\n\n if (highlight) {\n const prev = this.mml.slice(0, this.currentPosition);\n const current = this.mml.slice(this.currentPosition).replace(sequence.note, `<span class=\"x-highlight\">${sequence.note}</span>`);\n\n this.mml = `${prev}${current}`;\n\n this.currentPosition += this.mml.slice(this.currentPosition).indexOf('</span>') + '</span>'.length;\n } else {\n const prev = this.mml.slice(0, this.currentPosition);\n const current = sequence.note;\n\n this.mml = `${prev}${current}`;\n\n this.currentPosition += current.length;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.ready(0, sequence.duration).start(sequence.frequencies);\n this.callbacks.start(sequence);\n } else if (this.source instanceof OneshotModule) {\n for (let i = 0, len = sequence.indexes.length; i < len; i++) {\n if (sequence.indexes[i] !== -1) {\n this.source.ready(0, sequence.duration).start(sequence.indexes[i] + this.offset);\n }\n }\n\n this.callbacks.start(sequence, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.start(connects);\n this.callbacks.start(sequence);\n }\n\n this.timerid = window.setTimeout(() => {\n if (this.source instanceof OscillatorModule) {\n this.callbacks.stop(sequence);\n } else if (this.source instanceof OneshotModule) {\n this.callbacks.stop(sequence, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n this.callbacks.stop(sequence);\n }\n\n // for stopping MML\n this.previous = sequence;\n\n // Start next sequence\n this.start(highlight, connects);\n }, (sequence.duration * 1000));\n }\n\n /**\n * This method stops MML.\n */\n stop() {\n if (this.previous === null) {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.stop();\n this.callbacks.stop(this.previous);\n } else if (this.source instanceof OneshotModule) {\n for (const index of this.previous.indexes) {\n if (index !== -1) {\n this.source.stop((index + this.offset));\n }\n }\n\n this.callbacks.stop(this.previous, this.offset);\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n this.callbacks.stop(this.previous);\n }\n\n window.clearTimeout(this.timerid);\n this.timerid = null;\n }\n\n /**\n * This method is the getter for MML string.\n */\n getMML() {\n return this.mml;\n }\n\n /**\n * This method is the getter for sequence.\n */\n getSequence() {\n return this.sequences;\n }\n\n /**\n * This method determines whether the sequence exists.\n * @return {boolean} If the sequence exists, this value is `true`. Otherwise, this value is `false`.\n */\n hasSequence() {\n return this.sequences.length > 0;\n }\n\n /**\n * This method determines whether the MMLs are paused.\n * @return {boolean} If the MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n paused() {\n return this.timerid === null;\n }\n\n /**\n * This method is the getter for current sequence index.\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * This method is the setter for current sequence index.\n * @param {number} index This argument is the number that is new sequence index.\n */\n setCurrentIndex(index) {\n const i = parseInt(index, 10);\n\n if (i >= 0 && i < this.sequences.length) {\n this.currentIndex = i;\n }\n }\n}\n","'use strict';\n\nimport { Part } from './Part';\n\n/**\n * This class manages the instances of `Part` for playing the MML (Music Macro Language).\n * @constructor\n */\nexport class MML {\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context) {\n this.context = context;\n\n this.parts = []; /** @type {Array.<Part>} */\n\n this.callbacks = {\n 'start' : () => {},\n 'stop' : () => {},\n 'ended' : () => {},\n 'error' : () => {}\n };\n }\n\n /**\n * This method sets callback functions.\n * @param {string|object} key This argument is property name.\n * This argument is pair of property and value in the case of associative array.\n * @param {function} value This argument is callback function.\n * @return {MML} This is returned for method chain.\n */\n setup(key, value) {\n if ((arguments.length > 0) && (Object.prototype.toString.call(arguments[0]) === '[object Object]')) {\n // Associative array\n for (const k in arguments[0]) {\n this.setup(k, arguments[0][k]);\n }\n } else if (arguments.length > 1) {\n const k = String(key).toLowerCase();\n\n if (k in this.callbacks) {\n if (Object.prototype.toString.call(value) === '[object Function]') {\n this.callbacks[k] = value;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method parses MML string.\n * @param {OscillatorModule|OneshotModule|NoiseModule} source This argument is in order to select sound source.\n * @param {Array.<string>} mmls This argument is MML strings.\n * @param {number} offset This argument is in order to adjust the index of one-shot audio.\n * @return {Array.<Array.<Sequence>>} This is returned as array that contains `Sequence` for playing the MML.\n */\n ready(source, mmls, offset) {\n if (!Array.isArray(mmls) && (typeof mmls === 'string')) {\n mmls = [mmls];\n }\n\n if (!Array.isArray(mmls)) {\n return this;\n }\n\n this.stop();\n this.clear();\n\n this.mmls = mmls;\n\n for (const mml of mmls) {\n this.parts.push(new Part(source, mml, this.callbacks, offset));\n }\n\n return this;\n }\n\n /**\n * This method starts the designated MML part. Moreover, this method schedules next sequence.\n * @param {number} part This argument is the part of MML.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Connectable>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n * @return {MML} This is returned for method chain.\n */\n start(part, highlight, connects) {\n const p = parseInt(part, 10);\n\n if ((p >= 0) && (p < this.parts.length)) {\n const part = this.parts[p];\n\n part.start(highlight, connects);\n }\n\n return this;\n }\n\n /**\n * This method stops the all of MML parts.\n * @return {MML} This is returned for method chain.\n */\n stop() {\n for (const part of this.parts) {\n part.stop();\n }\n\n return this;\n }\n\n /**\n * This method gets the array that contains string or object for playing the MML.\n * @param {number} index This argument is required in the case of designating MML part or sequence object.\n * @param {boolean} asMML This argument is 'mml' in the case of getting string or array as MML.\n * @return {Array.<string>|string|Array.<Array.<object>>|Array.<object>}\n */\n get(index, asMML) {\n const i = parseInt(index, 10);\n\n const mmls = [];\n const sequences = [];\n\n for (const part of this.parts) {\n mmls.push(part.getMML());\n sequences.push(part.getSequence());\n }\n\n if (asMML) {\n return ((i >= 0) && (i < this.parts.length)) ? this.parts[i].getMML() : mmls;\n }\n\n return ((i >= 0) && (i < this.parts.length)) ? this.parts[i].getSequence() : sequences;\n }\n\n /**\n * This method starts or stops MML according to state.\n * @param {number} part This argument is the part of MML.\n * @param {boolean} highlight This argument is `true` in the case of surrounding by `span.x-highlight`.\n * @param {Array.<Connectable>|Array.<AudioNode>} connects This argument is the array for changing the default connection.\n * @return {MML} This is returned for method chain.\n */\n toggle(part, highlight, connects) {\n if (this.isPaused()) {\n this.start(part, highlight, connects);\n } else {\n this.stop();\n }\n\n return this;\n }\n\n /**\n * This method determines whether the sequences exist.\n * @return {boolean} If the sequences exist, this value is `true`. Otherwise, this value is `false`.\n */\n isSequences() {\n return (this.parts.length > 0) && this.parts.every(part => part.hasSequence());\n }\n\n /**\n * This method determines whether the MMLs are paused.\n * @return {boolean} If the MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n isPaused() {\n return (this.parts.length === 0) || this.parts.every(part => part.paused());\n }\n\n /**\n * This method gets or sets current sequence index.\n * @param {number} part This argument is the part of MML.\n * @param {number} index If this argument is number, this is new sequence index.\n * If this argument is omitted, this method is getter for current sequence index.\n * @return {number|MML} This is returned as current sequence index. Otherwise, this is returned for method chain.\n */\n currentIndex(part, index) {\n const p = parseInt(part, 10);\n\n if ((p < 0) || (p >= this.parts.length)) {\n return this;\n }\n\n if (index === undefined) {\n return this.parts[p].getCurrentIndex();\n }\n\n this.parts[p].setCurrentIndex(index);\n\n return this;\n }\n\n /**\n * This method converts MML to ABC Notation.\n * @param {string} mml This argument is MML string.\n * @param {number} X This argument is file number in ABC Notation.\n * @param {string} T This argument is title in ABC Notation.\n * @param {string} M This argument is beat in ABC Notation.\n * @param {string} L This argument is note duration in ABC Notation.\n * @param {string} K This argument is tone in ABC Notation.\n * @return {string} This is returned as ABC Notation.\n */\n toABC(mml, X, T, M, L, K) {\n let abc = '';\n\n abc += `X:${X ? X : 1}\\n`;\n abc += `T:${T ? T : ''}\\n`;\n abc += `M:${M ? M : '4/4'}\\n`;\n abc += `L:${L ? L : '1/256'}\\n`;\n abc += `K:${K ? K : ''}\\n`;\n\n const notes = mml.match(/\\s*(?:T\\d+)\\s*|\\s*(?:O\\d+)\\s*|\\s*(?:(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)(?:&(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)*\\s*/gi);\n\n if (notes === null) {\n return abc;\n }\n\n let octave = null;\n let totalDuration = 0;\n\n while (notes.length > 0) {\n const note = notes.shift().trim();\n\n if (/T\\d+/i.test(note)) {\n const Q = parseInt(note.slice(1), 10);\n\n if (Q <= 0) {\n return abc;\n }\n\n abc += `Q:1/4=${Q}\\n`;\n } else if (/O\\d+/i.test(note)) {\n octave = parseInt(note.slice(1), 10);\n\n if (octave < 0) {\n return abc;\n }\n } else if (/(?:(?:[CDEFGABR][#+-]?)+)(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)(?:&(?:[CDEFGABR][#+-]?)+(?:256|192|144|128|96|72|64|48|36|32|24|18|16|12|8|6|4|2|1)\\.?)*/i.test(note)) {\n if (octave === null) {\n return abc;\n }\n\n let splittedNotes = null;\n\n if (note.indexOf('&') === -1) {\n splittedNotes = [note];\n } else {\n splittedNotes = note.split('&');\n }\n\n let chord = '';\n\n while (splittedNotes.length > 0) {\n const splittedNote = splittedNotes.shift();\n\n const duration = parseInt(splittedNote.replace(/^.+?(\\d+)\\.*$/, '$1'), 10);\n\n let n = '';\n let d = 0;\n\n switch (duration) {\n case 1:\n n = splittedNote.replace('1', '256');\n break;\n case 2:\n n = splittedNote.replace('2', '128');\n break;\n case 4:\n n = splittedNote.replace('4', '64');\n break;\n case 8:\n n = splittedNote.replace('8', '32');\n break;\n case 16:\n n = splittedNote.replace('16', '16');\n break;\n case 32:\n n = splittedNote.replace('32', '8');\n break;\n case 64:\n n = splittedNote.replace('64', '4');\n break;\n case 128:\n n = splittedNote.replace('128', '2');\n break;\n case 256:\n n = splittedNote.replace('256', '1');\n break;\n // Tuplet\n case 6:\n n = `(3${splittedNote.replace('6', '128')}`;\n d = 128 / 3;\n break;\n case 12:\n n = `(3${splittedNote.replace('12', '64')}`;\n d = 64 / 3;\n break;\n case 18:\n n = `(9${splittedNote.replace('18', '128')}`;\n d = 128 / 9;\n break;\n case 24:\n n = `(3${splittedNote.replace('24', '32')}`;\n d = 32 / 3;\n break;\n case 36:\n n = `(9${splittedNote.replace('36', '64')}`;\n d = 64 / 9;\n break;\n case 48:\n n = `(3${splittedNote.replace('48', '16')}`;\n d = 16 / 3;\n break;\n case 72:\n n = `(9${splittedNote.replace('72', '32')}`;\n d = 32 / 9;\n break;\n case 96:\n n = `(3${splittedNote.replace('96', '8')}`;\n d = 8 / 3;\n break;\n case 144:\n n = `(9${splittedNote.replace('144', '16')}`;\n d = 16 / 9;\n break;\n case 192:\n n = `(3${splittedNote.replace('192', '4')}`;\n d = 4 / 3;\n break;\n default:\n return abc;\n }\n\n if (n.indexOf('.') !== -1) {\n n = n.replace(/^(.+?)\\d+\\.+$/, `$1${1.5 * parseInt(n.replace(/^.+?(\\d+)\\.+$/, '$1'), 10)}`);\n }\n\n if (n.indexOf('(') === -1) {\n totalDuration += parseInt(n.replace(/^.+?(\\d+)\\.*$/i, '$1'), 10);\n } else {\n totalDuration += d;\n }\n\n if (totalDuration >= 256) {\n n += ' | ';\n totalDuration = 0;\n }\n\n if (/R/i.test(n)) {\n abc += `${n} `;\n continue;\n }\n\n let o = '';\n\n switch (octave) {\n case 0:\n o = ',,,,';\n break;\n case 1:\n o = ',,,';\n break;\n case 2:\n o = ',,';\n break;\n case 3:\n o = ',';\n break;\n case 5:\n o = '\\'';\n break;\n case 6:\n o = '\\'\\'';\n break;\n case 7:\n o = '\\'\\'\\'';\n break;\n case 4 :\n default:\n break;\n }\n\n const matches = n.match(/^(\\(\\d+)?((?:[CDEFGAB][#+-]?)+)(.*)$/i);\n\n if (matches === null) {\n return abc;\n }\n\n const tuplet = matches[1] ? matches[1] : '';\n const chordLength = matches[2].length;\n const restNote = matches[3] ? matches[3] : '';\n\n let start = 0;\n\n if (tuplet.length > 0) {\n n = n.replace(/^(?:\\(\\d+)?((?:[CDEFGAB][#+-]?)+)(.*)$/i, '$1$2');\n }\n\n if (chordLength === 1) {\n chord += `${tuplet}${n.slice(0, 1)}${o}${restNote}`;\n } else if ((chordLength === 2) && /[#+-]/.test(n.charAt(1))) {\n chord += `${tuplet}${n.slice(1, 2)}${n.slice(0, 1)}${o}${restNote}`;\n } else {\n while (start < chordLength) {\n if (start === 0) {\n chord += `${tuplet}[`;\n }\n\n if (/[#+-]/.test(n.charAt(start + 1))) {\n chord += `${n.slice((start + 1), (start + 2))}${n.slice(start, (start + 1))}${o}`;\n start += 2;\n } else {\n chord += `${n.slice(start, (start + 1))}${o}`;\n start++;\n }\n\n if (start === chordLength) {\n chord += `]${restNote}`;\n }\n }\n }\n\n if (splittedNotes.length > 0) {\n chord += '&';\n } else {\n abc += `${chord} `;\n }\n }\n }\n }\n\n return abc.replace(/R/gi, 'z')\n .replace(/[#+]/g, '^')\n .replace(/-/g, '_')\n .replace(/&/g, '-')\n .replace(/\\s{2}/g, ' ')\n .trim();\n }\n\n /**\n * This method clears the instances of `Part`.\n * @return {MML} This is returned for method chain.\n */\n clear() {\n for (const part of this.parts) {\n part.stop();\n }\n\n // Garbage Collection\n this.parts.length = 0;\n\n return this;\n }\n\n /** @override */\n toString() {\n return '[MML]';\n }\n}\n","'use strict';\n\n/**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\nexport function FFT(reals, imags, size) {\n const pow2 = n => Math.pow(2, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = -1 * Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n}\n\n/**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is the instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is the instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\nexport function IFFT(reals, imags, size) {\n const pow2 = n => Math.pow(2.0, n);\n\n const indexes = new Float32Array(size);\n\n const numberOfStages = Math.log2(size);\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n for (let i = 0; i < pow2(stage - 1); i++) {\n const rest = numberOfStages - stage;\n\n for (let j = 0; j < pow2(rest, 2); j++) {\n const n = i * pow2(rest + 1) + j;\n const m = pow2(rest) + n;\n const r = j * pow2(stage - 1);\n\n const areal = reals[n];\n const aimag = imags[n];\n const breal = reals[m];\n const bimag = imags[m];\n const creal = Math.cos((2.0 * Math.PI * r) / size);\n const cimag = Math.sin((2.0 * Math.PI * r) / size);\n\n if (stage < numberOfStages) {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = (creal * (areal - breal)) - (cimag * (aimag - bimag));\n imags[m] = (creal * (aimag - bimag)) + (cimag * (areal - breal));\n } else {\n reals[n] = areal + breal;\n imags[n] = aimag + bimag;\n reals[m] = areal - breal;\n imags[m] = aimag - bimag;\n }\n }\n }\n }\n\n for (let stage = 1; stage <= numberOfStages; stage++) {\n const rest = numberOfStages - stage;\n\n for (let i = 0; i < pow2(stage - 1); i++) {\n indexes[pow2(stage - 1) + i] = indexes[i] + pow2(rest);\n }\n }\n\n for (let k = 0; k < size; k++) {\n if (indexes[k] <= k) {\n continue;\n }\n\n const real = reals[indexes[k]];\n const imag = imags[indexes[k]];\n\n reals[indexes[k]] = reals[k];\n imags[indexes[k]] = imags[k];\n\n reals[k] = real;\n imags[k] = imag;\n }\n\n for (let k = 0; k < size; k++) {\n reals[k] /= size;\n imags[k] /= size;\n }\n}\n\n/**\n * This class (static) method gets audio data as `ArrayBuffer` by Ajax.\n * @param {string} url This argument is URL for audio resource.\n * @param {type} string This argument is response type that is one of 'text', 'arraybuffer', 'blob', 'document', 'json'. The default value is 'arraybuffer'.\n * @param {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when error occurred.\n * @param {function} progressCallback This argument is invoked during receiving audio data.\n */\nexport function ajax(url, type, timeout, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('url' in properties) {\n url = properties.url;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('timeout' in properties) {\n timeout = properties.timeout;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n // for errorCallback\n const ERROR_AJAX = 'error';\n const ERROR_AJAX_TIMEOUT = 'timeout';\n\n const xhr = new XMLHttpRequest();\n\n const t = parseInt(timeout, 10);\n\n xhr.timeout = (t > 0) ? t : 60000;\n\n xhr.ontimeout = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event, ERROR_AJAX_TIMEOUT);\n }\n };\n\n xhr.onprogress = event => {\n if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n xhr.onerror = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(event, ERROR_AJAX);\n }\n };\n\n xhr.onload = event => {\n if ((xhr.status === 200) && (Object.prototype.toString.call(successCallback) === '[object Function]')) {\n successCallback(event, xhr.response);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = /text|arraybuffer|blob|document|json/.test(String(type).toLowerCase()) ? String(type).toLowerCase() : 'arraybuffer';\n xhr.send(null);\n}\n\n/**\n * This class (static) method calculates minutes and seconds from the designated time in seconds.\n * @param {number} time This argument is the time in seconds.\n * @return {object} This is returned as associative array that contains `minutes`, `seconds` and `milliseconds` keys.\n */\nexport function convertTime(time) {\n const t = parseFloat(time);\n\n if (t >= 0) {\n const m = Math.floor(t / 60);\n const s = Math.floor(t % 60);\n const ms = t - Math.floor(t);\n\n return {\n 'minutes' : m,\n 'seconds' : s,\n 'milliseconds' : ms\n };\n }\n}\n\n/**\n * This class (static) method creates the instance of `AudioBuffer` from `ArrayBuffer`.\n * @param {AudioContext} context This argument is the instance of `AudioContext` for `decodeAudioData` method.\n * @param {ArrayBuffer} arrayBuffer This argument is converted to the instance of `AudioBuffer`.\n * @param {function} successCallback This argument is invoked when `decodeAudioData` method is successful.\n The 1st argument in this callback function is the instance of `AudioBuffer`.\n * @param {function} errorCallback This argument is invoked when `decodeAudioData` method failed.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function decode(context, arrayBuffer, successCallback, errorCallback) {\n if (!(context instanceof AudioContext)) {\n return;\n }\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n if (Object.prototype.toString.call(successCallback) !== '[object Function]') {\n successCallback = () => {};\n }\n\n if (Object.prototype.toString.call(errorCallback) !== '[object Function]') {\n errorCallback = () => {};\n }\n\n return context.decodeAudioData(arrayBuffer, successCallback, errorCallback);\n}\n\n/**\n * This class (static) method shows `Element` in original size from full screen.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function exitFullscreen() {\n if (document.exitFullscreen) {\n return document.exitFullscreen();\n }\n\n if (document.webkitCancelFullScreen) {\n return document.webkitCancelFullScreen();\n }\n\n if (document.mozCancelFullScreen) {\n return document.mozCancelFullScreen();\n }\n\n if (document.msExitFullscreen) {\n return document.msExitFullscreen();\n }\n\n if (document.cancelFullScreen) {\n return document.cancelFullScreen();\n }\n\n return Promise.reject('Cannot exit from full screen.');\n}\n\n/**\n * This class (static) method gets the instance of `File` (extends `Blob`).\n * @param {Event} event This argument is the instance of Event by Drag & Drop or `<input type=\"file\">`.\n * @param {string} type This argument is one of 'ArrayBuffer', 'DataURL', 'ObjectURL', 'Text', 'JSON'.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when reading file failed.\n * @param {function} progressCallback This argument is invoked as `onprogress` event handler in the instance of `FileReader`.\n * @return {File|ObjectURL} This is returned as the instance of `File` (extends `Blob`) or Object URL.\n */\nexport function file(event, type, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('event' in properties) {\n event = properties.event;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!(event instanceof Event)) {\n return;\n }\n\n // for the instance of `File` (extends `Blob`)\n let file = null;\n\n if (event.type === 'drop') {\n // Drag & Drop\n event.stopPropagation();\n event.preventDefault();\n\n file = /* ('items' in event.dataTransfer) ? event.dataTransfer.items[0].getAsFile() : */event.dataTransfer.files[0];\n } else if ((event.type === 'change') && ('files' in event.target)) {\n // `<input type=\"file\">`\n file = event.target.files[0];\n } else {\n return;\n }\n\n if (!(file instanceof File)) {\n throw new Error('Please upload file.');\n } else if ((/text/i.test(type)) && !file.type.includes('text')) {\n throw new Error('Please upload text file.');\n } else if (/json/i.test(type) && !file.type.includes('application/json')) {\n throw new Error('Please upload JSON file.');\n } else if ((/arraybuffer|dataurl/i.test(type)) && !/audio|video/.test(file.type)) {\n throw new Error('Please upload audio or video file.');\n } else {\n if (/objecturl/i.test(type)) {\n return window.URL.createObjectURL(file);\n }\n\n read({\n 'file' : file,\n 'type' : type,\n 'success' : successCallback,\n 'error' : errorCallback,\n 'progress' : progressCallback\n });\n\n return file;\n }\n}\n\n/**\n * This class (static) method reads file of audio or text.\n * @param {Blob} file This argument is the instance of `Blob`. This is entity of file.\n * @param {string} type This argument is one of 'ArrayBuffer', 'DataURL', 'Text'.\n * @param {function} successCallback This argument is invoked as next process when reading file is successful.\n * @param {function} errorCallback This argument is invoked when reading file failed.\n * @param {function} progressCallback This argument is invoked as `onprogress` event handler in the instance of `FileReader`.\n */\nexport function read(file, type, successCallback, errorCallback, progressCallback) {\n // The argument is associative array ?\n if (Object.prototype.toString.call(arguments[0]) === '[object Object]') {\n const properties = arguments[0];\n\n if ('file' in properties) {\n file = properties.file;\n }\n\n if ('type' in properties) {\n type = properties.type;\n }\n\n if ('success' in properties) {\n successCallback = properties.success;\n }\n\n if ('error' in properties) {\n errorCallback = properties.error;\n }\n\n if ('progress' in properties) {\n progressCallback = properties.progress;\n }\n }\n\n if (!(file instanceof Blob)) {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n errorCallback(null, 'FILE_IS_NOT_BLOB');\n }\n\n return;\n }\n\n const reader = new FileReader();\n\n reader.onprogress = event => {\n if (Object.prototype.toString.call(progressCallback) === '[object Function]') {\n progressCallback(event);\n }\n };\n\n reader.onerror = event => {\n if (Object.prototype.toString.call(errorCallback) === '[object Function]') {\n let error = '';\n\n switch (reader.error.code) {\n case reader.error.NOT_FOUND_ERR:\n error = 'NOT_FOUND_ERR';\n break;\n case reader.error.SECURITY_ERR:\n error = 'SECURITY_ERR';\n break;\n case reader.error.ABORT_ERR:\n error = 'ABORT_ERR';\n break;\n case reader.error.NOT_READABLE_ERR:\n error = 'NOT_READABLE_ERR';\n break;\n case reader.error.ENCODING_ERR:\n error = 'ENCODING_ERR';\n break;\n default:\n error = 'ERR';\n break;\n }\n\n errorCallback(event, error);\n }\n };\n\n reader.onload = event => {\n if (Object.prototype.toString.call(successCallback) === '[object Function]') {\n let result = reader.result;\n\n // Escape `<script>` in the case of text\n if ((typeof result === 'string') && !result.includes('data:') && !result.indexOf('blob:')) {\n result = result.replace(/<(\\/?script.*?)>/gi, '&lt;$1&gt;');\n }\n\n successCallback(event, result);\n }\n };\n\n if (/arraybuffer/i.test(type)) {\n reader.readAsArrayBuffer(file);\n } else if (/dataurl/i.test(type)) {\n reader.readAsDataURL(file);\n } else if (/text|json/i.test(type)) {\n reader.readAsText(file, 'UTF-8');\n }\n}\n\n/**\n * This class (static) method shows the designated `Element` in full screen.\n * @param {Element} element This argument is the instance of `Element` that is the target of full screen.\n * @return {Promise} This is returned as `Promise`.\n */\nexport function requestFullscreen(element) {\n if (!(element instanceof Element)) {\n return Promise.reject('Invalid argument.');\n }\n\n if (element.requestFullscreen) {\n return element.requestFullscreen();\n }\n\n if (element.webkitRequestFullscreen) {\n return element.webkitRequestFullscreen();\n }\n\n if (element.mozRequestFullScreen) {\n return element.mozRequestFullScreen();\n }\n\n if (element.msRequestFullscreen) {\n return element.msRequestFullscreen();\n }\n\n return Promise.reject('Cannot change to full screen.');\n}\n\n/**\n * This class (static) method calculates frequency from the index that corresponds to the 12 equal temperament.\n * @param {Array.<number>} indexes This argument is array of index that corresponds to the 12 equal temperament.\n * For example, This value is between 0 and 88 in the case of piano.\n * @return {Array.<number>} This is returned as array that contains frequencies.\n */\nexport function toFrequencies(indexes) {\n // The 12 equal temperament\n //\n // Min -> 27.5 Hz (A), Max -> 4186 Hz (C)\n //\n // A * 1.059463 -> A# (half up)\n\n const FREQUENCY_RATIO = Math.pow(2, (1 / 12)); // about 1.059463\n const MIN_A = 27.5;\n\n if (!Array.isArray(indexes)) {\n indexes = [indexes];\n }\n\n const frequencies = new Array(indexes.length);\n\n for (let i = 0, len = indexes.length; i < len; i++) {\n const index = parseInt(indexes[i], 10);\n\n frequencies[i] = (index >= 0) ? (MIN_A * Math.pow(FREQUENCY_RATIO, index)) : 0;\n }\n\n return frequencies;\n}\n\n/**\n * This class (static) method creates text file.\n * @param {string} text This argument is string.\n * @return {string} This is returned as text file.\n */\nexport function toTextFile(text) {\n /**\n * This function converts string to ASCII string.\n * @param {string} string This argument is string.\n * @return {string} This is returned as string that is converted to ASCII string.\n */\n const toAscii = string => {\n let converted = '';\n\n for (let i = 0, len = string.length; i < len; i++) {\n const charCode = string.charCodeAt(i);\n\n if (charCode > 0xFF) {\n converted += `&#${charCode};`;\n } else {\n converted += string.charAt(i);\n }\n }\n\n return converted;\n };\n\n const base64 = window.btoa(toAscii(String(text)));\n const dataURL = `data:text/plain;base64,${base64}`;\n\n return dataURL;\n}\n","'use strict';\n\nimport { SoundModule } from './SoundModule';\nimport { OscillatorModule } from './OscillatorModule';\nimport { OneshotModule } from './OneshotModule';\nimport { NoiseModule } from './NoiseModule';\nimport { AudioModule } from './AudioModule';\nimport { MediaModule } from './MediaModule';\nimport { StreamModule } from './StreamModule';\nimport { MixerModule } from './MixerModule';\nimport { ProcessorModule } from './ProcessorModule';\nimport { MIDI } from './MIDI';\nimport { MML } from './MML';\nimport { Analyser } from './SoundModule/Analyser';\nimport { Recorder } from './SoundModule/Recorder';\nimport { Session } from './SoundModule/Session';\nimport { Effector } from './SoundModule/Effectors/Effector';\nimport { Autopanner } from './SoundModule/Effectors/Autopanner';\nimport { Chorus } from './SoundModule/Effectors/Chorus';\nimport { Compressor } from './SoundModule/Effectors/Compressor';\nimport { Delay } from './SoundModule/Effectors/Delay';\nimport { Distortion } from './SoundModule/Effectors/Distortion';\nimport { Equalizer } from './SoundModule/Effectors/Equalizer';\nimport { Filter } from './SoundModule/Effectors/Filter';\nimport { Flanger } from './SoundModule/Effectors/Flanger';\nimport { Listener } from './SoundModule/Effectors/Listener';\nimport { Panner } from './SoundModule/Effectors/Panner';\nimport { Phaser } from './SoundModule/Effectors/Phaser';\nimport { PitchShifter } from './SoundModule/Effectors/PitchShifter';\nimport { Reverb } from './SoundModule/Effectors/Reverb';\nimport { Ringmodulator } from './SoundModule/Effectors/Ringmodulator';\nimport { Stereo } from './SoundModule/Effectors/Stereo';\nimport { Tremolo } from './SoundModule/Effectors/Tremolo';\nimport { Wah } from './SoundModule/Effectors/Wah';\nimport {\n FFT,\n IFFT,\n ajax,\n convertTime,\n decode,\n exitFullscreen,\n file,\n requestFullscreen,\n read,\n toFrequencies,\n toTextFile\n} from './XSound';\n\nconst global = (typeof window !== 'undefined') ? window : {};\n\n// for legacy browsers\nglobal.AudioContext = global.AudioContext || global.webkitAudioContext;\nglobal.MediaSource = global.MediaSource || global.WebkitMediaSource;\nglobal.URL = global.URL || global.webkitURL || global.mozURL;\n\nglobal.requestAnimationFrame = global.requestAnimationFrame ||\n global.webkitRequestAnimationFrame ||\n global.mozRequestAnimationFrame ||\n (callback => global.setTimeout(callback, (1000 / 60)));\n\nglobal.cancelAnimationFrame = global.cancelAnimationFrame ||\n global.webkitCancelAnimationFrame ||\n global.mozCancelAnimationFrame ||\n global.clearTimeout;\n\nlet XSound;\n\nconst IS_XSOUND = Boolean(global.AudioContext);\n\nif (IS_XSOUND) {\n const audiocontext = new AudioContext();\n\n // for legacy browsers\n audiocontext.createScriptProcessor = audiocontext.createScriptProcessor || audiocontext.createJavaScriptNode;\n audiocontext.createGain = audiocontext.createGain || audiocontext.createGainNode;\n audiocontext.createDelay = audiocontext.createDelay || audiocontext.createDelayNode;\n audiocontext.createPeriodicWave = audiocontext.createPeriodicWave || audiocontext.createWaveTable;\n\n const sources = {\n 'oscillator' : new OscillatorModule(audiocontext),\n 'oneshot' : new OneshotModule(audiocontext),\n 'noise' : new NoiseModule(audiocontext),\n 'audio' : new AudioModule(audiocontext),\n 'media' : new MediaModule(audiocontext),\n 'stream' : new StreamModule(audiocontext),\n 'mixer' : new MixerModule(audiocontext),\n 'processor' : new ProcessorModule(audiocontext),\n 'midi' : new MIDI(audiocontext),\n 'mml' : new MML(audiocontext)\n };\n\n /**\n * This function is global object for getting the instance of `OscillatorModule` or `OneshotModule` or `NoiseModule` or `AudioModule` or `MediaModule` or `StreamModule` or `MixerModule` or `ProcessorModule` or `MIDI` or `MML` or `Oscillator`.\n * @param {string} source This argument is one of 'oscillator', 'oneshot', 'noise', 'audio', 'media', 'stream', 'mixer', 'processor', 'midi', 'mml'.\n * @param {number} index This argument is in order to select one of some oscillators.\n * @return {OscillatorModule|OneshotModule|NoiseModule|AudioModule|MediaModule|StreamModule|MixerModule|ProcessorModule|MIDI|MML|Oscillator}\n */\n XSound = (source, index) => {\n const s = String(source).replace(/-/g, '').toLowerCase();\n\n switch (s) {\n case 'oscillator':\n if (index === undefined) {\n return sources.oscillator;\n }\n\n const i = parseInt(index, 10);\n\n if ((i >= 0) && (i < sources.oscillator.length())) {\n return sources.oscillator.get(i);\n }\n\n return null;\n case 'oneshot' :\n case 'noise' :\n case 'audio' :\n case 'media' :\n case 'stream' :\n case 'mixer' :\n case 'processor':\n case 'midi' :\n case 'mml' :\n return sources[s];\n default :\n return null;\n }\n };\n\n /**\n * Class (Static) properties\n */\n XSound.IS_XSOUND = IS_XSOUND;\n XSound.SAMPLE_RATE = audiocontext.sampleRate;\n XSound.NUMBER_OF_INPUTS = SoundModule.NUMBER_OF_INPUTS;\n XSound.NUMBER_OF_OUTPUTS = SoundModule.NUMBER_OF_OUTPUTS;\n XSound.FFT = FFT;\n XSound.IFFT = IFFT;\n XSound.ajax = ajax;\n XSound.convertTime = convertTime;\n XSound.decode = decode;\n XSound.exitFullscreen = exitFullscreen;\n XSound.file = file;\n XSound.requestFullscreen = requestFullscreen;\n XSound.read = read;\n XSound.toFrequencies = toFrequencies;\n XSound.toTextFile = toTextFile;\n\n XSound.Analyser = Analyser;\n XSound.Recorder = Recorder;\n XSound.Session = Session;\n\n XSound.Effector = Effector;\n XSound.Autopanner = Autopanner;\n XSound.Chorus = Chorus;\n XSound.Compressor = Compressor;\n XSound.Delay = Delay;\n XSound.Distortion = Distortion;\n XSound.Equalizer = Equalizer;\n XSound.Filter = Filter;\n XSound.Flanger = Flanger;\n XSound.Listener = Listener;\n XSound.Panner = Panner;\n XSound.Phaser = Phaser;\n XSound.PitchShifter = PitchShifter;\n XSound.Reverb = Reverb;\n XSound.Ringmodulator = Ringmodulator;\n XSound.Stereo = Stereo;\n XSound.Tremolo = Tremolo;\n XSound.Wah = Wah;\n\n /**\n * This class (static) method changes state ('running') of `AudioContext`.\n * The initial state is 'suspended' by Autoplay Policy Change.\n * Therefore, this method must be invoked by user gestures.\n * @return {Promise} This is returned as `Promise`.\n */\n XSound.setup = () => {\n if (audiocontext.state !== 'running') {\n return audiocontext.resume();\n }\n\n return Promise.reject();\n };\n\n /**\n * This class (static) method returns function as closure that is getter of cloned module.\n * @return {function} This is returned as closure that is getter of cloned module.\n */\n XSound.clone = () => {\n const clones = {\n 'oscillator' : new OscillatorModule(audiocontext),\n 'oneshot' : new OneshotModule(audiocontext),\n 'noise' : new NoiseModule(audiocontext),\n 'audio' : new AudioModule(audiocontext),\n 'media' : new MediaModule(audiocontext),\n 'stream' : new StreamModule(audiocontext),\n 'mixer' : new MixerModule(audiocontext),\n 'processor' : new ProcessorModule(audiocontext),\n 'midi' : new MIDI(audiocontext),\n 'mml' : new MML(audiocontext)\n };\n\n const C = (source, index) => {\n const s = String(source).replace(/-/g, '').toLowerCase();\n\n switch (s) {\n case 'oscillator':\n if (index === undefined) {\n return clones.oscillator;\n }\n\n const i = parseInt(index, 10);\n\n if ((i >= 0) && (i < clones.oscillator.length())) {\n return clones.oscillator.get(i);\n }\n\n return null;\n case 'oneshot' :\n case 'noise' :\n case 'audio' :\n case 'media' :\n case 'stream' :\n case 'mixer' :\n case 'processor':\n case 'midi' :\n case 'mml' :\n return clones[s];\n default :\n return null;\n }\n };\n\n C.free = sourceList => {\n if (!Array.isArray(sourceList)) {\n sourceList = [sourceList];\n }\n\n for (const source of sourceList) {\n // Already deleted ?\n if (source === null) {\n continue;\n }\n\n for (const key in clones) {\n if (source === clones[key]) {\n clones[key] = null;\n }\n }\n }\n };\n\n // Closure\n return C;\n };\n\n /**\n * This class (static) method releases memory of unnecessary instances.\n * @param {Array.<SoundModule|MIDI|MML>} sourceList This argument is the array that contains the instances of `SoundModule` or `MIDI` or `MML`.\n */\n XSound.free = sourceList => {\n if (!Array.isArray(sourceList)) {\n sourceList = [sourceList];\n }\n\n for (const source of sourceList) {\n // Already deleted ?\n if (source === null) {\n continue;\n }\n\n for (const key in sources) {\n if (source === sources[key]) {\n sources[key] = null;\n }\n }\n }\n };\n\n /**\n * This class (static) method removes one of the global objects or both of the global objects.\n * @param {boolean} deep This argument is in order to select whether removing both of global objects.\n * If this value is `true`, both of global objects are removed.\n * @return {XSound}\n */\n XSound.noConflict = deep => {\n if (window.X === XSound) {\n window.X = undefined;\n }\n\n // both of global objects are removed ?\n if (deep && (window.XSound === XSound)) {\n window.XSound = undefined;\n }\n\n return XSound;\n };\n\n /**\n * This class (static) method gets the instance of `AudioContext`.\n * @return {AudioContext}\n */\n XSound.get = () => {\n return audiocontext;\n };\n\n /**\n * This class (static) method gets `currentTime` property in the instance of `AudioContext`.\n * @return {number}\n */\n XSound.getCurrentTime = () => {\n return audiocontext.currentTime;\n };\n\n /** @override */\n XSound.toString = () => {\n return '[XSound]';\n };\n\n // for Autoplay Policy\n const setup = () => {\n XSound.setup().then(() => {}).catch(() => {});\n\n document.removeEventListener('click', setup, true);\n document.removeEventListener('mousedown', setup, true);\n document.removeEventListener('mouseup', setup, true);\n document.removeEventListener('touchstart', setup, true);\n document.removeEventListener('touchend', setup, true);\n };\n\n document.addEventListener('click', setup, true);\n document.addEventListener('mousedown', setup, true);\n document.addEventListener('mouseup', setup, true);\n document.addEventListener('touchstart', setup, true);\n document.addEventListener('touchend', setup, true);\n} else {\n XSound = () => null;\n\n XSound.IS_XSOUND = IS_XSOUND;\n}\n\n// for `<script>`\nglobal.XSound = XSound;\nglobal.X = XSound; // Alias of `XSound`\n\n// for ESModules and SSR (Server Side Rendering)\nif (typeof exports !== 'undefined') {\n exports.XSound = XSound;\n exports.X = XSound; // Alias of `XSound`\n}\n"],"names":["Connectable","Visualizer","sampleRate","this","isActive","graphics","canvas","context","svg","interval","timerid","styles","element","HTMLCanvasElement","CANVAS","getContext","SVGElement","SVG","key","value","k","String","replace","toLowerCase","v","undefined","parseFloat","shape","wave","grad","Array","isArray","isError","grads","offset","isNaN","Object","prototype","toString","call","prop","test","font","parseInt","data","minDecibels","maxDecibels","drawOnCanvas","drawBySVG","toDataURL","outerHTML","state","Boolean","innerWidth","innerHeight","middle","nPlotInterval","CanvasRenderingContext2D","Float32Array","w","h","m","strokeStyle","lineWidth","width","lineCap","cap","lineJoin","join","beginPath","i","len","length","x","left","y","top","moveTo","lineTo","stroke","fillStyle","upside","gradient","createLinearGradient","gradients","addColorStop","color","fillRect","linearGradientId","path","document","createElementNS","XMLNS","d","setAttribute","defs","createSVGLinearGradient","g","appendChild","rect","linearGradient","stop","size","style","family","height","clearRect","innerHTML","TimeOverview","savedImage","currentTime","sprite","plotInterval","textInterval","isDown","mode","DRAG_MODE_UPDATE","offsetX","startTime","endTime","onStart","bind","onMove","onEnd","arguments","param","r","DRAG_MODE_SPRITE","querySelector","SVG_SPRITE_CLASS_NAME","removeChild","right","bottom","Math","floor","nTextInterval","drawTimeDomainFloat32ArrayOnCanvas","grid","text","t","createFontString","fillText","measureText","trim","getImageData","getAttribute","drawTimeDomainFloat32ArrayBySVG","SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW","textContent","weight","classList","add","SVG_CURRENT_TIME_CLASS_NAME","time","ImageData","putImageData","baseX","abs","baseRect","lastElementChild","previousElementSibling","callback","drawNode","start","move","end","navigator","userAgent","removeEventListener","window","addEventListener","event","type","offsetLeft","parentNode","Element","scrollLeft","update","draw","getOffsetX","preventDefault","pageX","touches","Time","UINT","FLOAT","ceil","SVG_LINEAR_GRADIENT_ID_TIME","FFT","max","mindB","maxdB","range","drawnSize","fsDivN","f","slice","SVG_LINEAR_GRADIENT_ID_FFT","Analyser","analyser","createAnalyser","input","createGain","connect","timeOverviewL","timeOverviewR","fft","fftSize","smoothingTimeConstant","frequencyBinCount","domain","channel","buffer","c","AudioBuffer","numberOfChannels","set","getChannelData","Uint8Array","getByteTimeDomainData","getFloatTimeDomainData","requestAnimationFrame","setTimeout","getByteFrequencyData","getFloatFrequencyData","cancelAnimationFrame","clearTimeout","toUpperCase","Track","trackNumber","dataBlocks","dataBlock","push","Channel","channelNumber","tracks","channelGain","track","gain","Recorder","bufferSize","numberOfInputs","numberOfOutputs","processor","createScriptProcessor","channels","activeTrack","paused","numberOfTracks","n","append","hasTrack","gainL","gainR","trackL","get","trackR","onaudioprocess","inputLs","inputBuffer","inputRs","recordedLs","recordedRs","disconnect","every","hasChannel","some","has","flattenTrack","j","sum","numberOfElements","currentBlock","index","numberOfMaxBlocks","mixedValues","currentTrack","clear","qbit","soundLs","soundRs","mixTrack","flatTrack","CHANNEL","QBIT","SIZE","min","CHUNK_SIZE","RIFF_CHUNK","RATE","BPS","DATA_SIZE","sounds","binary","pow","Int16Array","base64","btoa","from","map","fromCodePoint","blob","Blob","URL","createObjectURL","Session","sender","BUFFER_SIZE","receiver","websocket","tls","host","port","openCallback","closeCallback","errorCallback","properties","open","close","error","scheme","charAt","p","WebSocket","binaryType","onopen","onclose","onerror","onmessage","ArrayBuffer","total","byteLength","BYTES_PER_ELEMENT","bufferLs","bufferRs","outputLs","outputBuffer","outputRs","destination","isConnected","bufferedAmount","send","readyState","OPEN","stateCallback","waitCallback","intervalid","setInterval","clearInterval","Effector","output","lfo","createOscillator","depth","rate","frequency","noteOn","noteOff","values","isStop","s","stopTime","releaseTime","JSON","stringify","params","Autopanner","panner","createStereoPanner","pan","AutopannerFallback","amplitudeL","amplitudeR","splitter","createChannelSplitter","merger","createChannelMerger","lfoSplitter","inputs","Chorus","delay","createDelay","mix","tone","createBiquadFilter","feedback","delayTime","LOWPASS","Q","SQRT1_2","depthRate","Compressor","compressor","createDynamicsCompressor","threshold","knee","ratio","attack","release","minValues","maxValues","Delay","MAX_DELAY_TIME","dry","wet","Distortion","distortion","createWaveShaper","drive","CLEAN","amount","numberOfSamples","BANDPASS","curve","createCurve","CRUNCH","OVERDRIVE","DISTORTION","FUZZ","curves","a","abx","exp","EnvelopeGenerator","generators","activeIndexes","activeCounter","decay","sustain","AudioNode","t0","t1","t2","t2Value","activeIndex","cancelScheduledValues","setValueAtTime","linearRampToValueAtTime","setTargetAtTime","useCurve","t3","t4","setValueCurveAtTime","setTargetValueAtTime","counter","MIN_GAIN","isDisconnect","generator","Equalizer","bass","treble","presence","LOWSHELF","PEAKING","HIGHSHELF","Filter","filter","maxFrequency","FILTER_TYPES","minFrequnecy","Flanger","Listener","listener","positions","forwards","ups","positionX","AudioParam","positionY","positionZ","z","setPosition","forwardX","forwardY","forwardZ","upX","upY","upZ","setOrientation","Panner","createPanner","orientations","refDistance","maxDistance","rolloffFactor","coneInnerAngle","coneOuterAngle","coneOuterGain","panningModel","HRTF","distanceModel","INVERSE_DISTANCE","orientationX","orientationY","orientationZ","PANNING_MODELS","DISTANCE_MODELS","Phaser","numberOfStages","filters","MAXIMUM_STAGES","ALLPASS","PitchShifter","pitch","realLs","realRs","imagLs","imagRs","arealLs","arealRs","aimagLs","aimagRs","eq","IFFT","reals","imags","pow2","indexes","log2","stage","rest","areal","aimag","breal","bimag","creal","cos","PI","cimag","sin","real","imag","Reverb","isLoadError","rirs","convolver","createConvolver","impulse","decodeAudioData","timeout","successCallback","progressCallback","success","progress","load","url","xhr","XMLHttpRequest","ontimeout","ERROR_AJAX_TIMEOUT","onprogress","abort","ERROR_AJAX","onload","status","arrayBuffer","response","audioBuffer","ERROR_DECODE","responseType","Ringmodulator","amplitude","Stereo","delayL","delayR","Tremolo","WAVE_TYPES","Wah","autoWah","lowpass","envelopeFollower","sensitivity","SoundModule","init","modules","mastervolume","INPUT","recorder","session","forEach","module","OUTPUT","NUMBER_OF_INPUTS","NUMBER_OF_OUTPUTS","stereo","wah","pitchshifter","equalizer","autopanner","tremolo","ringmodulator","phaser","flanger","chorus","reverb","envelopegenerator","name","effector","source","connects","Oscillator","setPeriodicWave","setWaveTable","volume","octave","fine","customs","MAX_SIZE","subarray","periodicWave","createPeriodicWave","OCTAVE","detune","Glide","frequencies","LINEAR","EXPONENTIAL","diff","oscillator","OscillatorModule","sources","times","isAnalyser","glide","states","setGenerator","duration","processCallback","ready","on","off","OneshotModule","resources","buffers","volumes","isStops","settings","transpose","loop","selectedIndex","bufferIndex","playbackRate","loopStart","loopEnd","createBufferSource","noteGrainOn","onended","AudioBufferSourceNode","oneshot","NoiseModule","WHITE_NOISE","PINK_NOISE","BROWNIAN_NOISE","getGenerator","lastOut","random","b0","b1","b2","b3","b4","b5","b6","white","VocalCanceler","dataL","dataR","AudioModule","callbacks","vocalcanceler","setup","b","decode","ended","isBuffer","dataLs","dataRs","createBuffer","copyToChannel","sprites","keys","reduce","audioBuffers","audio","isSource","MediaModule","media","ext","mse","sb","file","mimeType","controls","muted","autoplay","listeners","formats","HTMLAudioElement","AUDIO","HTMLVideoElement","VIDEO","format","canPlayType","MediaElementAudioSourceNode","createMediaElementSource","src","resume","then","catch","Error","loadstart","pause","HTMLMediaElement","isFinite","channelCount","endOfStream","revokeObjectURL","onSourceOpen","onSourceEnded","onSourceClose","onSourceBufferUpdateEnd","onSourceBufferError","MediaSource","isTypeSupported","removeAttribute","indexOf","message","position","play","pos","Promise","resolve","reject","addSourceBuffer","sourceopen","request","Request","fetch","appendBuffer","sourceended","sourceclose","updateend","pictureInPictureEnabled","disablePictureInPicture","pictureInPictureElement","requestPictureInPicture","exitPictureInPicture","NoiseGate","level","NoiseSuppressor","outputs","xreals","ximags","yreals","yimags","amplitudes","phases","sqrt","atan2","StreamModule","stream","constraints","each","noisegate","noisesuppressor","streamCallback","mediaDevices","getUserMedia","MediaStream","runAnalyser","audioTracks","getAudioTracks","createMediaStreamTrackSource","createMediaStreamSource","isStreaming","clearAudio","clearVideo","getVideoTracks","enumerateDevices","MixerModule","ProcessorModule","options","moduleURL","promise","AudioWorkletNode","Map","audioWorklet","addModule","ScriptProcessorNode","postMessage","onmessageerror","parameters","MIDI","midiAccess","sysex","requestMIDIAccess","inputIterator","outputIterator","next","done","o","TokenMap","TokenTypes","Token","token","Tokenizer","mml","tokens","split","reverse","notes","numbers","pop","SPACE","EOS","TEMPO","NOTE","REST","NUMBER","TIE","UNKNOWN","Tree","operator","node","space","indent","getToken","getOperator","TreeConstructor","tokenizer","syntaxTree","nextToken","getType","tree","MMLSyntaxError","ERRORS","concat","Sequence","note","sequence","toPlainObject","Sequencer","treeConstructor","sequences","timeOf4note","trees","parse","getLeft","getRight","getValue","free","leftToken","rightToken","digits","computeIndex","HALF_UP","SHARP","HALF_DOWN","EQUAL_TEMPERAMENT","console","assert","computeFrequency","numberOf4note","QUARTER_NOTE","includes","DOT","current","previous","pitchname","C","D","E","F","G","A","B","R","computedIndex","MIN_A","FREQUENCY_RATIO","Part","currentIndex","currentPosition","sequencer","highlight","prev","MML","parts","mmls","part","asMML","getMML","getSequence","isPaused","hasSequence","getCurrentIndex","setCurrentIndex","X","T","M","L","K","abc","match","totalDuration","shift","splittedNotes","chord","splittedNote","matches","tuplet","chordLength","restNote","read","reader","FileReader","code","NOT_FOUND_ERR","SECURITY_ERR","ABORT_ERR","NOT_READABLE_ERR","ENCODING_ERR","result","readAsArrayBuffer","readAsDataURL","readAsText","XSound","global","AudioContext","webkitAudioContext","WebkitMediaSource","webkitURL","mozURL","webkitRequestAnimationFrame","mozRequestAnimationFrame","webkitCancelAnimationFrame","mozCancelAnimationFrame","IS_XSOUND","audiocontext","createJavaScriptNode","createGainNode","createDelayNode","createWaveTable","SAMPLE_RATE","ajax","convertTime","exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen","cancelFullScreen","Event","stopPropagation","dataTransfer","files","target","File","requestFullscreen","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","toFrequencies","toTextFile","string","converted","charCode","charCodeAt","toAscii","clone","clones","sourceList","noConflict","deep","getCurrentTime","exports"],"sourceRoot":""}