xsound 4.2.3 → 4.2.4
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.
- package/build/types/SoundModule/Analyser/Spectrogram.d.ts +13 -7
- package/build/types/SoundModule/Analyser/Spectrogram.d.ts.map +1 -1
- package/build/types/SoundModule/Analyser/index.d.ts.map +1 -1
- package/build/xsound.js +1 -1
- package/build/xsound.js.LICENSE.txt +1 -1
- package/build/xsound.js.map +1 -1
- package/build/xsound.min.js +1 -1
- package/build/xsound.min.js.LICENSE.txt +1 -1
- package/build/xsound.min.js.map +1 -1
- package/package.json +6 -6
package/build/xsound.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xsound.js","mappings":"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","sources":["webpack://xsound/webpack/universalModuleDefinition","webpack://xsound/webpack/bootstrap","webpack://xsound/webpack/runtime/define property getters","webpack://xsound/webpack/runtime/hasOwnProperty shorthand","webpack://xsound/webpack/runtime/make namespace object","webpack://xsound/./src/worklet.ts","webpack://xsound/./src/SoundModule/SoundModuleProcessor.ts","webpack://xsound/./src/SoundModule/Analyser/Visualizer.ts","webpack://xsound/./src/SoundModule/Analyser/TimeOverview.ts","webpack://xsound/./src/SoundModule/Analyser/Time.ts","webpack://xsound/./src/SoundModule/Analyser/FFT.ts","webpack://xsound/./src/SoundModule/Analyser/Spectrogram.ts","webpack://xsound/./src/SoundModule/Analyser/index.ts","webpack://xsound/./src/SoundModule/Recorder/Frame.ts","webpack://xsound/./src/SoundModule/Recorder/Channel.ts","webpack://xsound/./src/SoundModule/Recorder/RecorderProcessor.ts","webpack://xsound/./src/SoundModule/Recorder/index.ts","webpack://xsound/./src/SoundModule/Effectors/Effector.ts","webpack://xsound/./src/SoundModule/Effectors/Autopanner.ts","webpack://xsound/./src/SoundModule/Effectors/BitCrusher.ts","webpack://xsound/./src/SoundModule/Effectors/Chorus.ts","webpack://xsound/./src/SoundModule/Effectors/Compressor.ts","webpack://xsound/./src/SoundModule/Effectors/Delay.ts","webpack://xsound/./src/SoundModule/Effectors/EnvelopeGenerator.ts","webpack://xsound/./src/SoundModule/Effectors/Equalizer.ts","webpack://xsound/./src/SoundModule/Effectors/Filter.ts","webpack://xsound/./src/SoundModule/Effectors/Flanger.ts","webpack://xsound/./src/SoundModule/Effectors/Fuzz.ts","webpack://xsound/./src/SoundModule/Effectors/Listener.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/NoiseGateProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/NoiseGate.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/NoiseSuppressorProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/NoiseSuppressor.ts","webpack://xsound/./src/SoundModule/Effectors/OverDrive.ts","webpack://xsound/./src/SoundModule/Effectors/Panner.ts","webpack://xsound/./src/SoundModule/Effectors/Phaser.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/PitchShifterProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/PitchShifter.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Cabinet.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Marshall.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/MesaBoogie.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Fender.ts","webpack://xsound/./src/SoundModule/Effectors/Preamp.ts","webpack://xsound/./src/SoundModule/Effectors/Reverb.ts","webpack://xsound/./src/SoundModule/Effectors/Ringmodulator.ts","webpack://xsound/./src/SoundModule/Effectors/Stereo.ts","webpack://xsound/./src/SoundModule/Effectors/Tremolo.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/VocalCancelerProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/VocalCanceler.ts","webpack://xsound/./src/SoundModule/Effectors/Wah.ts","webpack://xsound/./src/SoundModule/index.ts","webpack://xsound/./src/OscillatorModule/OscillatorModuleProcessor.ts","webpack://xsound/./src/OscillatorModule/Glide.ts","webpack://xsound/./src/OscillatorModule/Oscillator.ts","webpack://xsound/./src/OscillatorModule/index.ts","webpack://xsound/./src/OneshotModule/OneshotModuleProcessor.ts","webpack://xsound/./src/OneshotModule/index.ts","webpack://xsound/./src/NoiseModule/NoiseModuleProcessor.ts","webpack://xsound/./src/NoiseModule/index.ts","webpack://xsound/./src/AudioModule/AudioModuleProcessor.ts","webpack://xsound/./src/AudioModule/index.ts","webpack://xsound/./src/MediaModule/MediaModuleProcessor.ts","webpack://xsound/./src/MediaModule/index.ts","webpack://xsound/./src/StreamModule/StreamModuleProcessor.ts","webpack://xsound/./src/StreamModule/index.ts","webpack://xsound/./src/ProcessorModule/index.ts","webpack://xsound/./src/MixerModule/MixerModuleProcessor.ts","webpack://xsound/./src/MixerModule/index.ts","webpack://xsound/./src/MIDI/index.ts","webpack://xsound/./src/worker.ts","webpack://xsound/./src/MML/Token.ts","webpack://xsound/./src/MML/Tokenizer.ts","webpack://xsound/./src/MML/Tree.ts","webpack://xsound/./src/MML/TreeConstructor.ts","webpack://xsound/./src/XSound/index.ts","webpack://xsound/./src/MML/Sequence.ts","webpack://xsound/./src/MML/Sequencer.ts","webpack://xsound/./src/MML/ScheduleWorker.ts","webpack://xsound/./src/MML/Part.ts","webpack://xsound/./src/MML/index.ts","webpack://xsound/./src/main.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"xsound\"] = factory();\n\telse\n\t\troot[\"xsound\"] = factory();\n})(self, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// HACK:\nexport type FrozenArray<T> = Array<T>;\n\nexport type Inputs = FrozenArray<FrozenArray<Float32Array>>;\nexport type Outputs = FrozenArray<FrozenArray<Float32Array>>;\nexport type Parameters = { [parameterName: string]: Float32Array };\n\n/**\n * This class enables to use inline AudioWorklet.\n */\nexport abstract class AudioWorkletProcessor {\n protected port = new MessagePort();\n protected abstract process(inputs: Inputs, outputs: Outputs, parameters: Parameters): boolean;\n\n // eslint-disable-next-line no-useless-constructor\n constructor(_options?: AudioWorkletNodeOptions) {\n }\n}\n\n/**\n * This class extends `AudioWorkletProcessor`.\n */\nexport abstract class OverlapAddProcessor extends AudioWorkletProcessor {\n private static readonly RENDER_QUANTUM_SIZE = 128;\n\n protected frameSize = 2048;\n protected hopSize = 128;\n protected numberOfOverlaps: number;\n\n private inputBuffers: Inputs = [[]];\n private inputBuffersHead: Inputs = [[]];\n private inputBuffersToSend: Inputs = [[]];\n\n private outputBuffers: Outputs = [[]];\n private outputBuffersToRetrieve: Outputs = [[]];\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n if (options.processorOptions) {\n this.frameSize = options.processorOptions.frameSize ?? 2048;\n }\n\n this.numberOfOverlaps = this.frameSize / this.hopSize;\n\n this.allocateInputChannels(1);\n this.allocateOutputChannels(1);\n }\n\n protected abstract processOverlapAdd(inputs: Inputs, outputs: Outputs, parameters: Parameters): void;\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs, parameters: Parameters): boolean {\n this.reallocateChannelsIfNeeded(inputs, outputs);\n\n this.readInputs(inputs);\n this.shiftInputBuffers();\n this.prepareInputBuffersToSend();\n this.processOverlapAdd(this.inputBuffersToSend, this.outputBuffersToRetrieve, parameters);\n this.handleOutputBuffersToRetrieve();\n this.writeOutputs(outputs);\n this.shiftOutputBuffers();\n\n return true;\n }\n\n private reallocateChannelsIfNeeded(inputs: Inputs, outputs: Outputs): void {\n const inputNumberOfChannels = inputs[0].length;\n\n if (inputNumberOfChannels !== this.inputBuffers[0].length) {\n this.allocateInputChannels(inputNumberOfChannels);\n }\n\n const outputNumberOfChannels = outputs[0].length;\n\n if (outputNumberOfChannels !== this.outputBuffers[0].length) {\n this.allocateOutputChannels(outputNumberOfChannels);\n }\n }\n\n private allocateInputChannels(numberOfChannels: number): void {\n this.inputBuffers = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.inputBuffers[0][channelNumber] = new Float32Array(this.frameSize + OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n }\n\n this.inputBuffersHead = [[]];\n this.inputBuffersToSend = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.inputBuffersHead[0][channelNumber] = this.inputBuffers[0][channelNumber].subarray(0, this.frameSize);\n this.inputBuffersToSend[0][channelNumber] = new Float32Array(this.frameSize);\n }\n }\n\n private allocateOutputChannels(numberOfChannels: number): void {\n this.outputBuffers = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.outputBuffers[0][channelNumber] = new Float32Array(this.frameSize);\n }\n\n this.outputBuffersToRetrieve = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.outputBuffersToRetrieve[0][channelNumber] = new Float32Array(this.frameSize);\n }\n }\n\n private readInputs(inputs: Inputs): void {\n if (inputs[0].length && (inputs[0][0].length === 0)) {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].fill(0, this.frameSize);\n }\n\n return;\n }\n\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].set(inputs[0][channelNumber], this.frameSize);\n }\n }\n\n private writeOutputs(outputs: Outputs): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n outputs[0][channelNumber].set(this.outputBuffers[0][channelNumber].subarray(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE));\n }\n }\n\n private shiftInputBuffers(): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].copyWithin(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n }\n }\n\n private shiftOutputBuffers(): void {\n for (let channelNumber = 0; channelNumber < this.outputBuffers[0].length; channelNumber++) {\n this.outputBuffers[0][channelNumber].copyWithin(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n this.outputBuffers[0][channelNumber].subarray(this.frameSize - OverlapAddProcessor.RENDER_QUANTUM_SIZE).fill(0);\n }\n }\n\n private prepareInputBuffersToSend(): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffersToSend[0][channelNumber].set(this.inputBuffersHead[0][channelNumber]);\n }\n }\n\n private handleOutputBuffersToRetrieve(): void {\n for (let channelNumber = 0; channelNumber < this.outputBuffers[0].length; channelNumber++) {\n for (let n = 0; n < this.frameSize; n++) {\n this.outputBuffers[0][channelNumber][n] += this.outputBuffersToRetrieve[0][channelNumber][n] / this.numberOfOverlaps;\n }\n }\n }\n}\n\n/**\n * This function creates AudioWorklet script as Data URL.\n * @param {AudioWorkletGlobalScope.AudioWorkletProcessor} processor This argument is class that extends `AudioWorkletProcessor`.\n * @return {string} Return value is AudioWorklet script as Data URL.\n */\nexport function createModule(processor: new (options: AudioWorkletNodeOptions) => AudioWorkletProcessor): string {\n return `data:text/javascript,${encodeURIComponent(OverlapAddProcessor.toString())}; ${encodeURIComponent(processor.toString())}; registerProcessor('${processor.name}', ${processor.name})`;\n}\n\n/**\n * This function adds module as AudioWorklet.\n * @param {AudioContext} context This argument is instance of `AudioContext` for adding AudioWorklet module.\n * @param {AudioWorkletGlobalScope.AudioWorkletProcessor} processor This argument is class that extends `AudioWorkletProcessor`.\n * @param {WorkletOptions} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise<void>} Return value is `Promise` that `addModule` returns.\n */\nexport function addAudioWorklet(context: AudioContext, processor: new (options: AudioWorkletNodeOptions) => AudioWorkletProcessor, options?: WorkletOptions): Promise<void> {\n return context.audioWorklet.addModule(createModule(processor), options);\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n * However, this processor is not used.\n */\nexport class SoundModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { Statable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { SoundModule } from '../../SoundModule';\n\nexport type Color = string;\n\nexport type GraphicsApi = 'canvas' | 'svg' | '';\n\nexport type Gradient = {\n offset: number,\n color: string\n};\n\nexport type Gradients = Gradient[];\n\nexport type Shape = 'line' | 'rect';\n\nexport type Font = {\n family?: string,\n size?: string,\n style?: string,\n weight?: string\n};\n\nexport type GraphicsStyles = {\n shape?: Shape,\n gradients?: Gradients,\n wave?: Color,\n grid?: Color,\n text?: Color,\n font?: Font,\n width?: number,\n cap?: CanvasLineCap,\n join?: CanvasLineJoin,\n top?: number,\n right?: number,\n bottom?: number,\n left?: number\n};\n\nexport type SpectrumScale = 'linear' | 'logarithmic';\n\nexport type VisualizerParams = {\n interval?: number,\n styles?: GraphicsStyles\n};\n\n/**\n * This private class is superclass for visualizer class (`TimeOverview`, `Time`, `FFT`).\n */\nexport abstract class Visualizer implements Statable {\n public static readonly XMLNS = 'http://www.w3.org/2000/svg' as const;\n public static readonly XLINK = 'http://www.w3.org/1999/xlink' as const;\n\n protected static SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW = 'svg-linear-gradient-time-overview';\n protected static SVG_LINEAR_GRADIENT_ID_TIME = 'svg-linear-gradient-time';\n protected static SVG_LINEAR_GRADIENT_ID_FFT = 'svg-linear-gradient-fft';\n\n protected sampleRate: number;\n protected channel: ChannelNumber;\n protected analyser: AnalyserNode | null = null;\n\n protected isActive = false;\n protected graphics: GraphicsApi = '';\n\n protected canvas: HTMLCanvasElement | null = null;\n protected context: CanvasRenderingContext2D | null = null;\n\n protected svg: SVGSVGElement | null = null;\n\n protected interval = 1000; // msec\n\n protected styles: GraphicsStyles = {\n shape : 'line',\n gradients: [\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 weight: '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 * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode | null = null) {\n this.sampleRate = sampleRate;\n this.channel = channel;\n this.analyser = analyser;\n }\n\n /**\n * This method sets up for using Canvas or SVG.\n * @param {HTMLCanvasElement|SVGSVGElement} element This argument is either `HTMLCanvasElement` or `SVGSVGElement`.\n * @return {Visualizer} Return value is for method chain.\n */\n public setup(element: HTMLCanvasElement | SVGSVGElement) {\n if (element instanceof HTMLCanvasElement) {\n this.graphics = 'canvas';\n this.canvas = element;\n this.context = this.canvas.getContext('2d');\n } else if (element instanceof SVGSVGElement) {\n this.graphics = 'svg';\n this.svg = element;\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method connects sound source to analyser node.\n * @param {SoundModule|AudioNode} source This argument is either `SoundModule` or `AudioNode`.\n * @return {Visualizer} Return value is for method chain.\n */\n public connect(source: SoundModule | AudioNode) {\n if (this.analyser === null) {\n return this;\n }\n\n if (source instanceof AudioNode) {\n source.connect(this.analyser);\n return;\n }\n\n source.OUTPUT.connect(this.analyser);\n\n return this;\n }\n\n /**\n * This method visualizes sound wave to Canvas or SVG. This method conceals difference of API for visualization.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\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} Return value is for method chain.\n */\n public start(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number) {\n switch (this.graphics) {\n case 'canvas': {\n this.visualizeOnCanvas(data, minDecibels, maxDecibels);\n break;\n }\n\n case 'svg': {\n this.visualizeBySVG(data, minDecibels, maxDecibels);\n break;\n }\n\n default: {\n break;\n }\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method gets or sets parameters for visualization.\n * This method is overloaded for type interface and type check.\n * @param {keyof VisualizerParams|VisualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {VisualizerParams[keyof VisualizerParams]} Return value is parameter for visualization if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'interval'): number;\n public param(params: 'styles'): GraphicsStyles;\n public param(params: VisualizerParams): void;\n public param(params: keyof VisualizerParams | VisualizerParams): VisualizerParams[keyof VisualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'interval': {\n return this.interval;\n }\n\n case 'styles': {\n return this.styles;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'interval': {\n if (typeof value === 'number') {\n this.interval = value;\n }\n\n break;\n }\n\n case 'styles': {\n if (typeof value === 'object') {\n this.styles = { ...this.styles, ...value };\n }\n\n break;\n }\n }\n }\n }\n\n /**\n * This method gets instance of `HTMLCanvasElement` or `SVGSVGElement`.\n * @return {HTMLCanvasElement|SVGSVGElement|null}\n */\n public get(): HTMLCanvasElement | SVGSVGElement | null {\n switch (this.graphics) {\n case 'canvas': {\n return this.canvas;\n }\n\n case 'svg': {\n return this.svg;\n }\n\n default: {\n return null;\n }\n }\n }\n\n /**\n * This method clears graphics.\n * @return {Visualizer} Return value is for method chain.\n */\n public clear() {\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas && this.context) {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n break;\n }\n\n case 'svg': {\n if (this.svg) {\n this.svg.innerHTML = '';\n }\n\n break;\n }\n\n default: {\n break;\n }\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method creates visualized graphics as string (Data URL or `Blob` or SVG).\n * @param {string} mimeType This argument is string that indicates image format. The default value is `image/octet-stream`.\n * @property {BlobCallback} callback This argument is callback function with resulting instance of `Blob`.\n * @property {string} type This argument is string that indicates image format. The default value is `image/png`.\n * @property {number} quality This argument is number between `0` and `1` that indicates image quality.\n * @return {string|void}\n */\n public create(mimeType?: string, params?: {\n callback: BlobCallback,\n type?: string,\n quality?: number,\n }): string | void {\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return '';\n }\n\n if ((typeof mimeType === 'string') && /^image\\/.+$/.test(mimeType)) {\n return this.canvas.toDataURL(mimeType);\n }\n\n if (params) {\n const { callback, type, quality } = params;\n\n return this.canvas.toBlob(callback, type, quality);\n }\n\n return this.canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');\n }\n\n case 'svg': {\n if (this.svg === null) {\n return '';\n }\n\n return this.svg.outerHTML;\n }\n\n default: {\n return '';\n }\n }\n }\n\n /**\n * This method gets visualizer state. If returns `true`, visualizer is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates visualizer.\n * @return {Visualizer} Return value is for method chain.\n */\n public activate() {\n this.isActive = true;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method deactivates visualizer.\n * @return {Visualizer} Return value is for method chain.\n */\n public deactivate() {\n this.isActive = false;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method visualizes time domain data (`Float32Array`) to Canvas.\n * @param {CanvasRenderingContext2D} context This argument is instance of `CanvasRenderingContext2D`.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is width of visualization area.\n * @param {number} innerHeight This argument is height of visualization area.\n * @param {number} middle This argument is middle of visualization area.\n * @param {number} numberOfPlots This argument is interval for visualization.\n */\n protected visualizeTimeDomainFloat32ArrayOnCanvas(context: CanvasRenderingContext2D, data: Float32Array, innerWidth: number, innerHeight: number, middle: number, numberOfPlots?: number): void {\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n\n // Begin visualization\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n for (let n = 0, len = data.length; n < len; n++) {\n if (!numberOfPlots || ((n % numberOfPlots) === 0)) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - data[n]) * (innerHeight / 2)) + top;\n\n if (n === 0) {\n context.moveTo((x + (context.lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let n = 0, len = data.length; n < len; n++) {\n if (!numberOfPlots || ((n % numberOfPlots) === 0)) {\n const x = ((n / len) * innerWidth) + left;\n const y = -1 * (data[n] * (innerHeight / 2));\n\n // Set style\n if (this.styles.gradients) {\n const upside = (innerHeight / 2) + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, middle, lineWidth, y);\n }\n }\n\n break;\n }\n }\n }\n\n /**\n * This method visualizes time domain data (`Float32Array`) to SVG.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is width of visualization area.\n * @param {number} innerHeight This argument is height of visualization area.\n * @param {number} middle This argument is middle of visualization area.\n * @param {number} numberOfPlots This argument is interval for visualization.\n * @param {string} linearGradientId This argument is `id` attribute for `SVGLinearGradientElement`.\n * @return {SVGPathElement|SVGGElement} This value is instance of `SVGPathElement` or `SVGGElement`.\n */\n protected visualizeTimeDomainFloat32ArrayBySVG(data: Float32Array, innerWidth: number, innerHeight: number, middle: number, numberOfPlots: number, linearGradientId: string): SVGPathElement | SVGGElement | null {\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfPlots) === 0) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - data[n]) * (innerHeight / 2)) + top;\n\n if (n === 0) {\n d += `M${x + ((this.styles.width ?? 1.5) / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n return path;\n }\n\n case 'rect': {\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(linearGradientId);\n }\n\n // Visualize wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfPlots) === 0) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((n / len) * innerWidth) + left;\n const y = data[n] * (innerHeight / 2);\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', middle.toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', ((defs === null) ? waveColor : `url(#${linearGradientId})`));\n\n g.appendChild(rect);\n }\n }\n\n return g;\n }\n\n default: {\n return null;\n }\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 value is as instance of `SVGDefsElement`.\n */\n protected createSVGLinearGradient(linearGradientId: string): SVGDefsElement | null {\n if (!this.styles.gradients) {\n return null;\n }\n\n const defs = document.createElementNS(Visualizer.XMLNS, 'defs');\n const linearGradient = document.createElementNS(Visualizer.XMLNS, 'linearGradient');\n\n linearGradient.setAttribute('id', 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.gradients) {\n const stop = document.createElementNS(Visualizer.XMLNS, 'stop');\n\n stop.setAttribute('offset', gradients.offset.toString(10));\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 styles.\n * @return {string}\n */\n protected createFontString(): string {\n const { style, weight, size, family } = this.styles.font ?? {};\n\n return `${style ?? 'normal'} ${weight ?? 'normal'} ${size ?? '13px'} \"${family ?? 'Arial'}\"`;\n }\n\n protected abstract visualizeOnCanvas(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void;\n protected abstract visualizeBySVG(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void;\n}\n","import type { ChannelNumber } from '../../types';\nimport type { VisualizerParams, Color, GraphicsStyles } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type MouseEventTypes = 'mousedown' | 'mousemove' | 'mouseup' | 'touchstart' | 'touchmove' | 'touchend';\n\nexport type DragMode = 'update' | 'sprite';\n\nexport type DragCallbackFunction = (event: MouseEvent | TouchEvent, startTime: number, endTime: number, mode: DragMode, direction: boolean) => void;\n\nexport type CurrentTimeStyles = {\n width?: number, // Not used currently\n color?: Color\n};\n\nexport type TimeOverviewParams = VisualizerParams & {\n currentTime?: CurrentTimeStyles,\n sprite?: Color,\n plotInterval?: number,\n textInterval?: number,\n mode?: DragMode\n};\n\nconst SVG_CURRENT_TIME_CLASS_NAME = 'xsound-svg-current-time';\nconst SVG_SPRITE_CLASS_NAME = 'xsound-svg-sprite';\n\n/**\n * This private class visualizes audio wave overview in time domain.\n */\nexport class TimeOverview extends Visualizer {\n private callback: DragCallbackFunction = () => {};\n\n private currentImageData: ImageData | null = null;\n private currentSVGElement: Element | null = null;\n private currentDataSize = 0;\n\n // for `update`, `drag`\n // This style is used for rectangle that displays audio current time\n private currentTime: CurrentTimeStyles = {\n width: 1,\n color: 'rgba(0, 0, 0, 0.5)'\n };\n\n // This style is used for rectangle that displays sprite range\n private sprite: Color = 'rgba(255, 255, 255, 0.25)';\n\n private plotInterval = 0.0625;\n private textInterval = 60;\n\n private isDown = false;\n private mode: DragMode = 'update';\n\n private offsetX = 0;\n private startTime = 0;\n private endTime = 0;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n */\n constructor(sampleRate: number, channel: ChannelNumber) {\n super(sampleRate, channel);\n\n this.onMouseStart = this.onMouseStart.bind(this);\n this.onMouseMove = this.onMouseMove.bind(this);\n this.onMouseUp = this.onMouseUp.bind(this);\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n }\n\n /**\n * This method gets or sets parameters for visualizing audio wave.\n * This method is overloaded for type interface and type check.\n * @param {keyof TimeOverviewParams|TimeOverviewParams} params This argument is string if getter. Otherwise, setter.\n * @return {TimeOverviewParams[keyof TimeOverviewParams]|TimeOverview} Return value is parameter for visualizing audio wave if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'currentTime'): CurrentTimeStyles;\n public override param(params: 'sprite'): Color;\n public override param(params: 'plotInterval'): number;\n public override param(params: 'textInterval'): number;\n public override param(params: 'mode'): DragMode;\n public override param(params: TimeOverviewParams): TimeOverview;\n public override param(params: keyof TimeOverviewParams | TimeOverviewParams): TimeOverviewParams[keyof TimeOverviewParams] | TimeOverview {\n if (typeof params === 'string') {\n switch (params) {\n case 'currentTime': {\n return this.currentTime;\n }\n\n case 'sprite': {\n return this.sprite;\n }\n\n case 'plotInterval': {\n return this.plotInterval;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'mode': {\n return this.mode;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'currentTime': {\n if (typeof value === 'object') {\n this.currentTime = { ...this.currentTime, ...value };\n }\n\n break;\n }\n\n case 'sprite': {\n if (typeof value === 'string') {\n this.sprite = value;\n }\n\n break;\n }\n\n case 'plotInterval': {\n if (typeof value === 'number') {\n this.plotInterval = value;\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n\n case 'mode': {\n if (typeof value === 'string') {\n if ((value === 'update') || (value === 'sprite')) {\n this.mode = value;\n }\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes audio current time on Canvas or SVG.\n * @param {number} time This argument is audio current time.\n * @return {TimeOverview} Return value is for method chain.\n */\n public update(time: number): TimeOverview {\n switch (this.graphics) {\n case 'canvas': {\n if (this.currentImageData === null) {\n return this;\n }\n\n if ((this.canvas === null) || (this.context === null)) {\n return this;\n }\n\n const context = this.context;\n const width = this.canvas.width;\n const height = this.canvas.height;\n\n const innerWidth = width - ((this.styles.left ?? 30) + (this.styles.right ?? 30));\n const innerHeight = height - ((this.styles.top ?? 15) + (this.styles.bottom ?? 15));\n const x = ((time * this.sampleRate) / this.currentDataSize) * innerWidth;\n const left = this.styles.left ?? 30;\n const top = this.styles.top ?? 15;\n\n const currentTimeColor = this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)';\n\n context.clearRect(0, 0, width, height);\n context.putImageData(this.currentImageData, 0, 0);\n\n switch (this.mode) {\n case 'update': {\n context.fillStyle = currentTimeColor;\n context.fillRect(left, (top + 1), x, (innerHeight - 1));\n\n break;\n }\n\n case 'sprite': {\n if (this.endTime !== 0) {\n const baseX = Math.trunc(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.currentDataSize) * innerWidth);\n\n context.fillStyle = this.sprite;\n\n if (x >= this.offsetX) {\n context.fillRect((left + this.offsetX), (top + 1), baseX, (innerHeight - 1));\n } else {\n context.fillRect((left + this.offsetX - baseX), (top + 1), baseX, (innerHeight - 1));\n }\n }\n\n context.fillStyle = currentTimeColor;\n\n if (x >= this.offsetX) {\n context.fillRect((left + this.offsetX), (top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n } else {\n context.fillRect((left + x), (top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n }\n\n break;\n }\n }\n\n break;\n }\n\n case 'svg': {\n if (this.currentSVGElement === null) {\n return this;\n }\n\n if (this.svg) {\n const rect = this.svg.querySelector(`.${SVG_CURRENT_TIME_CLASS_NAME}`);\n\n if (rect === null) {\n return this;\n }\n\n const width = Number((this.svg.getAttribute('width') ?? '0'));\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const x = ((time * this.sampleRate) / this.currentDataSize) * innerWidth;\n\n if (this.mode === 'update') {\n const spriteRect = this.svg.querySelector(`.${SVG_SPRITE_CLASS_NAME}`);\n\n if (spriteRect) {\n spriteRect.parentNode?.removeChild(spriteRect);\n }\n\n rect.setAttribute('x', left.toString(10));\n rect.setAttribute('width', x.toString(10));\n // rect.setAttribute('transform', `translate(${x} 0)`);\n rect.setAttribute('aria-label', 'current time');\n } else if (this.mode === 'sprite') {\n if (this.endTime !== 0) {\n const prevRect = this.svg.querySelector(`.${SVG_SPRITE_CLASS_NAME}`);\n\n if (prevRect) {\n prevRect.parentNode?.removeChild(prevRect);\n }\n\n const baseRect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n baseRect.classList.add(SVG_SPRITE_CLASS_NAME);\n\n const baseX = Math.trunc(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.currentDataSize) * innerWidth);\n\n baseRect.setAttribute('y', (top + 1).toString(10));\n baseRect.setAttribute('height', (rect.getAttribute('height') ?? '0'));\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', (left + this.offsetX).toString(10));\n } else {\n baseRect.setAttribute('x', (left + this.offsetX - baseX).toString(10));\n }\n\n baseRect.setAttribute('width', baseX.toString(10));\n\n this.svg.appendChild(baseRect);\n this.svg.appendChild(rect);\n }\n\n if (x >= this.offsetX) {\n rect.setAttribute('x', (left + this.offsetX).toString(10));\n } else {\n rect.setAttribute('x', (left + x).toString(10));\n }\n\n rect.setAttribute('width', Math.abs(x - this.offsetX).toString(10));\n rect.setAttribute('aria-label', 'sprite time');\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method registers event listener for updating current time or spriting audio by drag.\n * @param {DragCallbackFunction} callback This argument is invoked during drag.\n * @return {TimeOverview} Return value is for method chain.\n */\n public drag(callback?: DragCallbackFunction): TimeOverview {\n let visualizationNode: HTMLCanvasElement | Element | null = null;\n\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return this;\n }\n\n visualizationNode = this.canvas;\n break;\n }\n\n case 'svg': {\n if (this.svg === null) {\n return this;\n }\n\n visualizationNode = this.svg;\n break;\n }\n }\n\n if (visualizationNode === null) {\n return this;\n }\n\n if (callback) {\n this.callback = callback;\n }\n\n visualizationNode.removeEventListener('mousedown', { handleEvent: this.onMouseStart }, false);\n visualizationNode.removeEventListener('mousemove', { handleEvent: this.onMouseMove }, false);\n window.removeEventListener('mouseup', { handleEvent: this.onMouseUp }, false);\n\n visualizationNode.removeEventListener('touchstart', { handleEvent: this.onTouchStart }, false);\n visualizationNode.removeEventListener('touchmove', { handleEvent: this.onTouchMove }, false);\n window.removeEventListener('touchend', { handleEvent: this.onTouchEnd }, false);\n\n visualizationNode.addEventListener('mousedown', { handleEvent: this.onMouseStart }, false);\n visualizationNode.addEventListener('mousemove', { handleEvent: this.onMouseMove }, false);\n window.addEventListener('mouseup', { handleEvent: this.onMouseUp }, false);\n\n visualizationNode.addEventListener('touchstart', { handleEvent: this.onTouchStart }, false);\n visualizationNode.addEventListener('touchmove', { handleEvent: this.onTouchMove }, false);\n window.addEventListener('touchend', { handleEvent: this.onTouchEnd }, false);\n\n return this;\n }\n\n /**\n * This method visualizes audio wave overview to Canvas.\n * @param {Float32Array} data This argument is audio data for visualization.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive || (data instanceof Uint8Array)) {\n return;\n }\n\n const context = this.context;\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize wave at intervals of `this.plotInterval`\n const numberOfPlots = Math.trunc(this.plotInterval * this.sampleRate);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n this.visualizeTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, numberOfPlots);\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % numberOfTexts) === 0) {\n const x = Math.trunc((i / len) * innerWidth) + left;\n const t = `${Math.trunc((i / this.sampleRate) / 60)} min`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const t of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = Math.trunc(left - context.measureText(t).width);\n const y = Math.trunc((1 - Number(t.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.trunc(fontSize / 4)));\n }\n }\n }\n\n // for `update`, `drag`\n this.currentImageData = context.getImageData(0, 0, width, height);\n this.currentDataSize = data.length;\n\n // This rectangle displays audio current time\n context.fillStyle = this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)';\n context.fillRect(left, top, 1, innerHeight);\n }\n\n /**\n * This method visualizes audio wave overview to SVG.\n * @param {Float32Array} data This argument is audio data for visualization.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive || (data instanceof Uint8Array)) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize wave at intervals of `this.plotInterval`\n const numberOfPlots = Math.trunc(this.plotInterval * this.sampleRate);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin visualization\n const element = this.visualizeTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, numberOfPlots, `${TimeOverview.SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW}-${this.channel}`);\n\n if (element) {\n svg.appendChild(element);\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % numberOfTexts) === 0) {\n const x = Math.trunc((i / len) * innerWidth) + left;\n const t = `${Math.trunc((i / this.sampleRate) / 60)} min`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(TimeOverview.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + fontSize).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const t of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = left;\n const y = Math.trunc((1 - Number(t.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(TimeOverview.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n\n // This rectangle displays audio current time\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.classList.add(SVG_CURRENT_TIME_CLASS_NAME);\n\n rect.setAttribute('y', (top + 1).toString(10));\n rect.setAttribute('height', (innerHeight - 1).toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)'));\n\n svg.appendChild(rect);\n\n // for `update`, `drag`\n this.currentSVGElement = svg;\n this.currentDataSize = data.length;\n }\n\n /**\n * This method visualizes rectangle for audio current time.\n * @param {MouseEvent|TouchEvent} event This argument is instance of `MouseEvent` or `TouchEvent`.\n * @param {MouseEventTypes} type This argument is one of 'mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend'.\n * @param {number} offsetX This argument is X coordinate on Canvas or SVG from window.\n */\n private visualize(event: MouseEvent | TouchEvent, type: MouseEventTypes, offsetX: number): void {\n let offsetLeft = 0;\n let width = 0;\n\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return;\n }\n\n offsetLeft = this.canvas.offsetLeft;\n width = this.canvas.width;\n break;\n }\n\n case 'svg': {\n if (this.svg === null) {\n return;\n }\n\n offsetLeft = this.svg.parentElement?.offsetLeft ?? 0;\n width = Number((this.svg.getAttribute('width') ?? '0'));\n break;\n }\n }\n\n let x = offsetX - (offsetLeft + (this.styles.left ?? 30));\n\n if (this.graphics === 'canvas' && this.canvas?.parentElement) {\n x += this.canvas.parentElement.scrollLeft;\n }\n\n if (this.graphics === 'svg' && this.svg?.parentElement) {\n x += this.svg.parentElement.scrollLeft;\n }\n\n width -= ((this.styles.left ?? 30) + (this.styles.right ?? 30));\n\n // Exceed ?\n if (x < 0) { x = 0; }\n if (x > width) { x = width; }\n\n const plot = (x / width) * this.currentDataSize;\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\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseStart(event: MouseEvent): void {\n if (event.type === 'mousedown') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = true;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseMove(event: MouseEvent): void {\n if (!this.isDown) {\n return;\n }\n\n // Improve rendering performance by stopping event bubbling\n event.stopPropagation();\n\n if (event.type === 'mousemove') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseUp(event: MouseEvent): void {\n if (!this.isDown) {\n return;\n }\n\n if (event.type === 'mouseup') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = false;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchStart(event: TouchEvent): void {\n if (event.type === 'touchstart') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = true;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchMove(event: TouchEvent): void {\n if (!this.isDown) {\n return;\n }\n\n // Improve rendering performance by stopping event bubbling\n event.stopPropagation();\n\n // for Touch Panel\n event.preventDefault();\n\n if (event.type === 'touchmove') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchEnd(event: TouchEvent): void {\n if (!this.isDown) {\n return;\n }\n\n if (event.type === 'touchend') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = false;\n }\n\n /**\n * This method returns X coordinate from instance of `MouseEvent` or `TouchEvent`.\n * @param {MouseEvent|TouchEvent} event This argument is instance of `MouseEvent` or `TouchEvent`.\n * @return {number} Return value is X coordinate as mouse or touch position.\n */\n private getOffsetX(event: MouseEvent | TouchEvent): number {\n if (event instanceof MouseEvent) {\n return event.pageX;\n }\n\n if (event instanceof TouchEvent) {\n return event.touches[0].pageX;\n }\n\n return 0;\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { DataType } from '../Analyser';\nimport type { VisualizerParams, GraphicsStyles } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type TimeParams = VisualizerParams & {\n type?: DataType,\n textInterval?: number\n};\n\n/**\n * This private class visualizes sound wave in time domain.\n */\nexport class Time extends Visualizer {\n private type: DataType = 'uint';\n\n // Visualize text at intervals this value [sec]\n private textInterval = 0.005;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n // eslint-disable-next-line no-useless-constructor\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n }\n\n /**\n * This method gets or sets parameters for visualizing sound wave.\n * This method is overloaded for type interface and type check.\n * @param {keyof TimeParams|TimeParams} params This argument is string if getter. Otherwise, setter.\n * @return {TimeParams[keyof TimeParams]|Time} Return value is parameter for visualizing sound wave if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'type'): DataType;\n public override param(params: 'textInterval'): number;\n public override param(params: TimeParams): Time;\n public override param(params: keyof TimeParams | TimeParams): TimeParams[keyof TimeParams] | Time {\n if (typeof params === 'string') {\n switch (params) {\n case 'type': {\n return this.type;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'uint') || (value === 'float')) {\n this.type = value;\n }\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes sound wave in time domain to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n if (data instanceof Float32Array) {\n this.visualizeTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle);\n }\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - (data[n] / 255)) * innerHeight) + top;\n\n if (n === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = (0.5 - (data[n] / 255)) * innerHeight;\n\n // Set style\n if (this.styles.gradients) {\n const upside = (innerHeight / 2) + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, middle, 1, y);\n }\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfTexts) === 0) {\n const x = Math.trunc((n / len) * innerWidth) + left;\n\n const timeText = `${Math.ceil((n / this.sampleRate) * 1000)} ms`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(timeText, (x - (context.measureText(timeText).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const amplitudeText of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = Math.trunc((1 - Number(amplitudeText.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, (y - Math.trunc(fontSize / 4)));\n }\n }\n }\n }\n\n /**\n * This method visualizes sound wave in time domain to SVG.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Begin visualization\n svg.innerHTML = '';\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n if (data instanceof Float32Array) {\n const element = this.visualizeTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, 0, Time.SVG_LINEAR_GRADIENT_ID_TIME);\n\n if (element !== null) {\n svg.appendChild(element);\n }\n }\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(Time.XMLNS, 'path');\n\n let d = '';\n\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - (data[n] / 255)) * innerHeight) + top;\n\n if (n === 0) {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'rect': {\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(`${Time.SVG_LINEAR_GRADIENT_ID_TIME}-${this.channel}`);\n }\n\n // Visualize wave\n const g = document.createElementNS(Time.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let n = 0, len = data.length; n < len; n++) {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n const x = ((n / len) * innerWidth) + left;\n const y = ((data[n] / 255) - 0.5) * innerHeight;\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', middle.toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', ((defs === null) ? waveColor : `url(#${Time.SVG_LINEAR_GRADIENT_ID_TIME}-${this.channel})`));\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfTexts) === 0) {\n const x = Math.trunc((n / len) * innerWidth) + left;\n\n const timeText = `${Math.ceil((n / this.sampleRate) * 1000)} ms`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(Time.XMLNS, 'text');\n\n text.textContent = timeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + fontSize).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const amplitudeText of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = left;\n const y = Math.trunc((1 - Number(amplitudeText.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(Time.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { DataType } from '../Analyser';\nimport type { VisualizerParams, GraphicsStyles, SpectrumScale } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type FFTParams = VisualizerParams & {\n type?: DataType,\n size?: number,\n scale?: SpectrumScale,\n logarithmicFrequencies?: number[],\n textInterval?: number,\n readonly minFrequency?: number,\n readonly maxFrequency?: number\n};\n\n/**\n * This private class visualizes spectrum.\n */\nexport class FFT extends Visualizer {\n private type: DataType = 'uint';\n\n // Range for visualization\n private size = 256;\n\n private scale: SpectrumScale = 'linear';\n\n // for logarithmic\n private logarithmicFrequencies: number[] = [32, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];\n private minFrequency = this.logarithmicFrequencies[0];\n private maxFrequency = this.logarithmicFrequencies[this.logarithmicFrequencies.length - 1];\n private ratio = this.maxFrequency / this.minFrequency;\n private log10Ratio = Math.log10(this.ratio);\n\n // Visualize text at intervals of this value [Hz]\n private textInterval = 1000;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n // eslint-disable-next-line no-useless-constructor\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n }\n\n /**\n * This method gets or sets parameters for visualizing spectrum.\n * This method is overloaded for type interface and type check.\n * @param {keyof FFTParams|FFTParams} params This argument is string if getter. Otherwise, setter.\n * @return {FFTParams[keyof FFTParams]|FFT} Return value is parameter for visualizing spectrum if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'type'): DataType;\n public override param(params: 'size'): number;\n public override param(params: 'scale'): SpectrumScale;\n public override param(params: 'logarithmicFrequencies'): number[];\n public override param(params: 'minFrequency'): number;\n public override param(params: 'maxFrequency'): number;\n public override param(params: 'textInterval'): number;\n public override param(params: FFTParams): FFT;\n public override param(params: keyof FFTParams | FFTParams): FFTParams[keyof FFTParams] | FFT {\n if (typeof params === 'string') {\n switch (params) {\n case 'type': {\n return this.type;\n }\n\n case 'size': {\n return this.size;\n }\n\n case 'scale': {\n return this.scale;\n }\n\n case 'logarithmicFrequencies': {\n return this.logarithmicFrequencies;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'uint') || (value === 'float')) {\n this.type = value;\n }\n }\n\n break;\n }\n\n case 'size': {\n if (typeof value === 'number') {\n this.size = value;\n }\n\n break;\n }\n\n case 'scale': {\n if (typeof value === 'string') {\n if ((value === 'linear') || (value === 'logarithmic')) {\n this.scale = value;\n }\n }\n\n break;\n }\n\n case 'logarithmicFrequencies': {\n if (Array.isArray(value)) {\n this.logarithmicFrequencies = value;\n\n this.minFrequency = value[0];\n this.maxFrequency = value[value.length - 1];\n this.ratio = this.maxFrequency / this.minFrequency;\n this.log10Ratio = Math.log10(this.ratio);\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes spectrum to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrum.\n * @param {number} minDecibels This argument is in order to determine dB range of spectrum. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine db range of spectrum. The default value is -30 dB.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const mindB = minDecibels ?? -100;\n const maxdB = maxDecibels ?? -30;\n const range = maxdB - mindB;\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)'; // line only\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const actualSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / (2 * data.length);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval / frequencyResolution);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n switch (this.scale) {\n case 'linear': {\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n if (k === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n for (let k = 0, len = data.length; k < len; k++) {\n if (k === 0) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(y)) {\n continue;\n }\n\n if ((x < left) || (x > (left + innerWidth))) {\n continue;\n }\n\n if (k === 1) {\n context.moveTo((left + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n break;\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n context.beginPath();\n\n // Visualize wave\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = ((1 - (data[k] / 255)) * innerHeight) + top;\n\n if (k === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = -1 * ((data[k] / 255) * innerHeight);\n\n // Set style\n if (this.styles.gradients) {\n const upside = innerHeight + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, (innerHeight + top), lineWidth, y);\n }\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n if ((this.type === 'uint') || ((this.type === 'float') && (this.scale === 'linear'))) {\n for (let k = 0; k < actualSize; k++) {\n if ((k % numberOfTexts) === 0) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n\n const frequency = Math.trunc(this.textInterval * (k / numberOfTexts));\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(frequencyText, (x - (context.measureText(frequencyText).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n } else {\n this.logarithmicFrequencies.forEach((frequency: number) => {\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(frequencyText, (x - (context.measureText(frequencyText).width / 2)), (top + innerHeight + fontSize));\n }\n });\n }\n\n // Visualize grid and text (Y axis)\n switch (this.type) {\n case 'float': {\n for (let amplitude = mindB; amplitude <= maxdB; amplitude += 10) {\n const amplitudeText = `${amplitude} dB`;\n\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = Math.trunc(((-1 * (amplitude - maxdB)) / range) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, y);\n }\n }\n\n break;\n }\n\n case 'uint': {\n for (const amplitudeText of ['0.00', '0.25', '0.50', '0.75', '1.00']) {\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = ((1 - Number(amplitudeText)) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, y);\n }\n }\n\n break;\n }\n }\n }\n }\n\n /**\n * This method visualizes spectrum to SVG.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrum.\n * @param {number} minDecibels This argument is in order to determine dB range of spectrum. Default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine db range of spectrum. Default value is -30 dB.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const mindB = minDecibels ?? -100;\n const maxdB = maxDecibels ?? -30;\n const range = maxdB - mindB;\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)'; // line only\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const actualSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / (2 * data.length);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval / frequencyResolution);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n // Visualize wave\n const path = document.createElementNS(FFT.XMLNS, 'path');\n\n let d = '';\n\n switch (this.scale) {\n case 'linear': {\n for (let k = 0; k < actualSize; k++) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(x) || !Number.isFinite(y)) {\n continue;\n }\n\n if (d === '') {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n for (let k = 0; k < data.length; k++) {\n if (k === 0) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(y)) {\n continue;\n }\n\n if ((x < left) || (x > (left + innerWidth))) {\n continue;\n }\n\n if (d === '') {\n d += `M${x} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n break;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor); // line only\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(FFT.XMLNS, 'path');\n\n let d = '';\n\n for (let k = 0; k < actualSize; k++) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc((1 - (data[k] / 255)) * innerHeight) + top;\n\n if (k === 0) {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(`${FFT.SVG_LINEAR_GRADIENT_ID_FFT}-${this.channel}`);\n }\n\n // Visualize wave\n const g = document.createElementNS(FFT.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let k = 0; k < actualSize; k++) {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc((data[k] / 255) * innerHeight);\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (top + innerHeight).toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${top + innerHeight})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? waveColor : `url(#${FFT.SVG_LINEAR_GRADIENT_ID_FFT}-${this.channel})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n if ((this.type === 'uint') || ((this.type === 'float') && (this.scale === 'linear'))) {\n for (let k = 0; k < actualSize; k++) {\n if ((k % numberOfTexts) === 0) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n\n const frequency = Math.trunc(this.textInterval * (k / numberOfTexts));\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = frequencyText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + bottom).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n }\n } else {\n this.logarithmicFrequencies.forEach((frequency: number) => {\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = frequencyText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + bottom).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n });\n }\n\n // Visualize grid and text (Y axis)\n switch (this.type) {\n case 'float': {\n for (let amplitude = mindB; amplitude <= maxdB; amplitude += 10) {\n const amplitudeText = `${amplitude} dB`;\n\n const x = left;\n const y = Math.trunc(((-1 * (amplitude - maxdB)) / range) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (gridColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n\n case 'uint': {\n for (const amplitudeText of ['0.00', '0.25', '0.50', '0.75', '1.00']) {\n const x = left;\n const y = ((1 - Number(amplitudeText)) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n }\n }\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { VisualizerParams, GraphicsStyles, SpectrumScale } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type SpectrogramParams = VisualizerParams & {\n size?: number,\n scale?: SpectrumScale,\n duration?: number,\n plotInterval?: number,\n linearFrequencyTextInterval?: number,\n timeTextInterval?: number,\n logarithmicFrequencies?: number[],\n readonly minFrequency?: number,\n readonly maxFrequency?: number\n};\n\n/**\n * This private class visualizes spectrogram.\n */\nexport class Spectrogram extends Visualizer {\n private scale: SpectrumScale = 'logarithmic';\n\n private duration = 10;\n\n private plotInterval = 4;\n private linearFrequencyTextInterval = 8;\n private timeTextInterval = 16;\n private timeOffset = 1;\n private numberOfSamples = 0;\n\n private renderSize = 64;\n\n // for logarithmic\n private logarithmicFrequencies: number[] = [32, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];\n private minFrequency = this.logarithmicFrequencies[0];\n private maxFrequency = this.logarithmicFrequencies[this.logarithmicFrequencies.length - 1];\n private ratio = this.maxFrequency / this.minFrequency;\n\n private imagedata: ImageData | null = null;\n\n private colorFromNumber: ((data: Uint8Array[0]) => string) | null = null;\n\n /**\n * This function maps unsigned int 8 bits to color string by Jet colormap.\n * @param {Uint8Array[0]} data This argument is converted to color string based on Jet colormap.\n * @return {string} Return value is color string.\n */\n public static numberToJetColor(data: Uint8Array[0]): string {\n const rgba = 4 * (data / 255);\n\n const r = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 1.5), (0 - rgba + 4.5)) * 255)));\n const g = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 0.5), (0 - rgba + 3.5)) * 255)));\n const b = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba + 0.5), (0 - rgba + 2.5)) * 255)));\n\n return `rgb(${r} ${g} ${b})`;\n };\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n\n this.interval = 40;\n }\n\n /**\n * This method gets or sets parameters for visualizing spectrogram.\n * This method is overloaded for type interface and type check.\n * @param {keyof SpectrogramParams|SpectrogramParams} params This argument is string if getter. Otherwise, setter.\n * @return {SpectrogramParams[keyof SpectrogramParams]|Spectrogram} Return value is parameter for visualizing spectrogram if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'size'): number;\n public override param(params: 'scale'): SpectrumScale;\n public override param(params: 'duration'): number;\n public override param(params: 'plotInterval'): number;\n public override param(params: 'linearFrequencyTextInterval'): number;\n public override param(params: 'timeTextInterval'): number;\n public override param(params: 'logarithmicFrequencies'): number[];\n public override param(params: 'minFrequency'): number;\n public override param(params: 'maxFrequency'): number;\n public override param(params: SpectrogramParams): Spectrogram;\n public override param(params: keyof SpectrogramParams | SpectrogramParams): SpectrogramParams[keyof SpectrogramParams] | Spectrogram {\n if (typeof params === 'string') {\n switch (params) {\n case 'size': {\n return this.renderSize;\n }\n\n case 'scale': {\n return this.scale;\n }\n\n case 'duration': {\n return this.duration;\n }\n\n case 'plotInterval': {\n return this.plotInterval;\n }\n\n case 'linearFrequencyTextInterval': {\n return this.linearFrequencyTextInterval;\n }\n\n case 'timeTextInterval': {\n return this.timeTextInterval;\n }\n\n case 'logarithmicFrequencies': {\n return this.logarithmicFrequencies;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'size': {\n if (typeof value === 'number') {\n this.renderSize = value;\n }\n\n break;\n }\n\n case 'scale': {\n if (typeof value === 'string') {\n if ((value === 'linear') || (value === 'logarithmic')) {\n this.scale = value;\n }\n }\n\n break;\n }\n\n case 'duration': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.duration = value;\n }\n }\n\n break;\n }\n\n case 'plotInterval': {\n if (typeof value === 'number') {\n this.plotInterval = value;\n }\n\n break;\n }\n\n case 'linearFrequencyTextInterval': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.linearFrequencyTextInterval = value;\n }\n }\n\n break;\n }\n\n case 'timeTextInterval': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.timeTextInterval = value;\n }\n }\n\n break;\n }\n\n case 'logarithmicFrequencies': {\n if (Array.isArray(value)) {\n this.logarithmicFrequencies = value;\n\n this.minFrequency = value[0];\n this.maxFrequency = value[value.length - 1];\n this.ratio = this.maxFrequency / this.minFrequency;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method sets function that converts number to color string.\n * @param {function} func This argument is function that converts number to color string;\n * @return {Spectrogram} Return value is for method chain.\n */\n public setColorFromNumberFunction(func: ((data: Uint8Array[0]) => string) | null): Spectrogram {\n this.colorFromNumber = func;\n\n return this;\n }\n\n /**\n * This method visualizes spectrogram to Canvas.\n * @param {Uint8Array} data This argument is frequency domain data for spectrogram.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n\n const frequencyBinCount = data.length;\n const fftSize = 2 * frequencyBinCount;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / fftSize;\n\n const samples = this.duration * this.sampleRate;\n\n if (this.numberOfSamples >= samples) {\n this.imagedata = null;\n\n this.timeOffset = 1;\n this.numberOfSamples = 0;\n }\n\n if (this.imagedata === null) {\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Render Graph\n context.fillStyle = gridColor;\n context.fillRect(left, (top + innerHeight), innerWidth, 2);\n context.fillRect(left, top, 2, innerHeight);\n\n // Render coordinate\n context.fillStyle = textColor;\n context.font = this.createFontString();\n\n // X axis (time)\n context.textAlign = 'start';\n\n const textInterval = samples / this.timeTextInterval;\n\n for (let k = 0; k < samples; k++) {\n if ((k % textInterval) !== 0) {\n continue;\n }\n\n const x = k * (innerWidth / samples) + left;\n const y = top + innerHeight + parseInt((this.styles.font?.size ?? '13'), 10);\n\n const time = (k / samples) * this.duration;\n\n if ((time !== 0) && (time < 0.0001)) {\n context.fillText(`${(time * 1000).toFixed(1)} msec`, x, y);\n } else {\n context.fillText(`${time.toFixed(2)} sec`, x, y);\n }\n }\n\n context.textAlign = 'end';\n\n // Y axis (frequency)\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n for (let k = 0; k <= length; k++) {\n if ((k % this.linearFrequencyTextInterval) !== 0) {\n continue;\n }\n\n const x = left;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const frequency = k * frequencyResolution;\n\n context.fillText(`${Math.trunc(frequency)} Hz`, x, y);\n }\n\n break;\n }\n\n case 'logarithmic': {\n this.logarithmicFrequencies.forEach((frequency: number, index: number) => {\n const x = left;\n const y = ((1 - (index / this.logarithmicFrequencies.length)) * innerHeight) + top;\n\n if (frequency >= 1000) {\n context.fillText(`${Math.trunc(frequency / 1000)} kHz`, x, y);\n } else {\n context.fillText(`${frequency} Hz`, x, y);\n }\n });\n\n break;\n }\n }\n } else {\n context.putImageData(this.imagedata, 0, 0);\n }\n\n // Render spectrogram\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const h = parseInt((this.styles.font?.size ?? '13'), 10);\n\n for (let k = 0; k < length; k++) {\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const x = left + this.timeOffset;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y - h), 1, h);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y - h), 1, h);\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n const log10Ratio = Math.log10(this.ratio);\n\n const h = innerHeight / (this.logarithmicFrequencies.length - 1);\n\n for (let k = 0; k < frequencyBinCount; k++) {\n if (k === 0) {\n continue;\n }\n\n if ((k !== 1) && ((k % this.plotInterval) !== 0)) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = left + this.timeOffset;\n const y = ((1 - (log10FrequencyRatio / log10Ratio)) * innerHeight) + top;\n\n if (y < top) {\n continue;\n }\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y > (top + innerHeight - h) ? (top + innerHeight - h) : y), 1, h);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y > (top + innerHeight - h) ? (top + innerHeight - h) : y), 1, h);\n }\n }\n\n break;\n }\n }\n\n // Render time text\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.textAlign = 'center';\n\n this.numberOfSamples += frequencyBinCount;\n\n this.timeOffset = (this.numberOfSamples * (1 / this.sampleRate)) * (innerWidth / this.duration);\n\n this.imagedata = context.getImageData(0, 0, width, height);\n }\n\n /**\n * This method visualizes spectrogram to SVG.\n * @param {Uint8Array} data This argument is frequency domain data for spectrogram.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const frequencyBinCount = data.length;\n const fftSize = 2 * frequencyBinCount;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / fftSize;\n\n const samples = this.duration * this.sampleRate;\n\n if (this.numberOfSamples >= samples) {\n svg.innerHTML = '';\n\n this.timeOffset = 1;\n this.numberOfSamples = 0;\n }\n\n if (svg.innerHTML.length === 0) {\n // Render Graph\n const rectX = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n rectX.setAttribute('x', left.toString(10));\n rectX.setAttribute('y', (top + innerHeight).toString(10));\n rectX.setAttribute('width', innerWidth.toString(10));\n rectX.setAttribute('height', '2');\n rectX.setAttribute('fill', gridColor);\n rectX.setAttribute('stroke', 'none');\n\n const rectY = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n rectY.setAttribute('x', left.toString(10));\n rectY.setAttribute('y', top.toString(10));\n rectY.setAttribute('width', '2');\n rectY.setAttribute('height', innerHeight.toString(10));\n rectY.setAttribute('fill', gridColor);\n rectY.setAttribute('stroke', 'none');\n\n svg.appendChild(rectX);\n svg.appendChild(rectY);\n\n // Render coordinate\n\n // X axis (time)\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n const textInterval = samples / this.timeTextInterval;\n\n for (let k = 0; k < samples; k++) {\n if ((k % textInterval) !== 0) {\n continue;\n }\n\n const x = k * (innerWidth / samples) + left;\n const y = top + innerHeight + fontSize;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n const time = (k / samples) * this.duration;\n\n if ((time !== 0) && (time < 0.0001)) {\n text.textContent = `${(time * 1000).toFixed(1)} msec`;\n } else {\n text.textContent = `${time.toFixed(2)} sec`;\n }\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'start');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n }\n\n svg.appendChild(g);\n\n // Y axis (frequency)\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n for (let k = 0; k <= length; k++) {\n if ((k % this.linearFrequencyTextInterval) !== 0) {\n continue;\n }\n\n const x = left;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const frequency = k * frequencyResolution;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n text.textContent = `${Math.trunc(frequency)} Hz`;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n }\n\n svg.appendChild(g);\n\n break;\n }\n\n case 'logarithmic': {\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n this.logarithmicFrequencies.forEach((frequency: number, index: number) => {\n const x = left;\n const y = ((1 - (index / this.logarithmicFrequencies.length)) * innerHeight) + top;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n if (frequency >= 1000) {\n text.textContent = `${Math.trunc(frequency / 1000)} kHz`;\n } else {\n text.textContent = `${frequency} Hz`;\n }\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n });\n\n svg.appendChild(g);\n\n break;\n }\n }\n }\n\n // Render spectrogram\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const h = parseInt((this.styles.font?.size ?? '13'), 10);\n\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n for (let k = 0; k < length; k++) {\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const x = left + this.timeOffset;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const rect = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k]);\n\n rect.setAttribute('fill', color);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n rect.setAttribute('fill', color);\n }\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (y - h).toString(10));\n rect.setAttribute('width', (this.styles.width ? this.styles.width.toString(10) : '1'));\n rect.setAttribute('height', h.toString(10));\n rect.setAttribute('stroke', 'none');\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n\n case 'logarithmic': {\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n const log10Ratio = Math.log10(this.ratio);\n\n const h = innerHeight / (this.logarithmicFrequencies.length - 1);\n\n for (let k = 0; k < frequencyBinCount; k++) {\n if (k === 0) {\n continue;\n }\n\n if ((k !== 1) && ((k % this.plotInterval) !== 0)) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = left + this.timeOffset;\n const y = ((1 - (log10FrequencyRatio / log10Ratio)) * innerHeight) + top;\n\n if (y < top) {\n continue;\n }\n\n const rect = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k]);\n\n rect.setAttribute('fill', color);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n rect.setAttribute('fill', color);\n }\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (y > (top + innerHeight - h) ? (top + innerHeight - h) : y).toString(10));\n rect.setAttribute('width', (this.styles.width ? this.styles.width.toString(10) : '1'));\n rect.setAttribute('height', h.toString(10));\n rect.setAttribute('stroke', 'none');\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n\n this.numberOfSamples += frequencyBinCount;\n\n this.timeOffset = (this.numberOfSamples * (1 / this.sampleRate)) * (innerWidth / this.duration);\n }\n}\n","import type { Connectable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { Visualizer, VisualizerParams, Color, GraphicsApi, Gradient, Gradients, Shape, Font, GraphicsStyles, SpectrumScale } from './Visualizer';\nimport type { TimeOverviewParams, CurrentTimeStyles, MouseEventTypes, DragMode, DragCallbackFunction } from './TimeOverview';\nimport type { TimeParams } from './Time';\nimport type { FFTParams } from './FFT';\nimport type { SpectrogramParams } from './Spectrogram';\n\nimport { TimeOverview } from './TimeOverview';\nimport { Time } from './Time';\nimport { FFT } from './FFT';\nimport { Spectrogram } from './Spectrogram';\n\nexport type Domain = 'timeoverview' | 'time' | 'fft' | 'spectrogram';\nexport type DataType = 'uint' | 'float'; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\nexport type FFTSize = 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;\n\nexport type {\n Visualizer,\n VisualizerParams,\n Color,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n CurrentTimeStyles,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams\n};\n\nexport type AnalyserParams = {\n fftSize?: FFTSize,\n readonly frequencyBinCount?: number,\n minDecibels?: number,\n maxDecibels?: number,\n smoothingTimeConstant?: number\n};\n\n/**\n * This private class manages 3 private classes (`TimeOverview`, `Time`, `FFT`) for visualizing sound wave.\n */\nexport class Analyser implements Connectable {\n private analysers: [AnalyserNode, AnalyserNode];\n private splitter: ChannelSplitterNode;\n private input: GainNode;\n\n private timeOverviews: [TimeOverview, TimeOverview];\n private times: [Time, Time];\n private ffts: [FFT, FFT];\n private spectrograms: [Spectrogram, Spectrogram];\n\n private timeDomainAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private timeDomainTimerIds: [number | null, number | null] = [null, null];\n private frequencyDomainAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private frequencyDomainTimerIds: [number | null, number | null] = [null, null];\n private spectrogramAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private spectrogramTimerIds: [number | null, number | null] = [null, null];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.analysers = [context.createAnalyser(), context.createAnalyser()];\n this.splitter = context.createChannelSplitter(2);\n this.input = context.createGain();\n\n // GainNode (Input) -> ChannelSplitterNode (L / R) -> AnalyserNode\n this.input.connect(this.splitter);\n this.splitter.connect(this.analysers[0], 0, 0);\n this.splitter.connect(this.analysers[1], 1, 0);\n\n this.timeOverviews = [new TimeOverview(context.sampleRate, 0), new TimeOverview(context.sampleRate, 1)];\n this.times = [new Time(context.sampleRate, 0, this.analysers[0]), new Time(context.sampleRate, 1, this.analysers[1])];\n this.ffts = [new FFT(context.sampleRate, 0, this.analysers[0]), new FFT(context.sampleRate, 1, this.analysers[1])];\n this.spectrograms = [new Spectrogram(context.sampleRate, 0, this.analysers[0]), new Spectrogram(context.sampleRate, 1, this.analysers[1])];\n\n // Set default value\n this.analysers.forEach((analyser: AnalyserNode) => {\n analyser.fftSize = 2048;\n analyser.minDecibels = -100;\n analyser.maxDecibels = -30;\n analyser.smoothingTimeConstant = 0.8;\n });\n }\n\n /**\n * This method visualizes sound wave.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', 'spectrogram'.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AudioBuffer} buffer This argument is instance of `AudioBuffer` (If domain is 'timeoverview', this argument is required).\n * @return {Analyser} Return value is for method chain.\n */\n public start(domain: Domain, channelNumber?: ChannelNumber, buffer?: AudioBuffer): Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n this.input.disconnect(this.splitter);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n\n // GainNode (Input) -> AnalyserNode\n this.input.connect(this.analysers[0]);\n\n channel = 0;\n }\n\n switch (domain) {\n case 'timeoverview': {\n if (buffer && (buffer.numberOfChannels > channel)) {\n const data = new Float32Array(buffer.length);\n\n data.set(buffer.getChannelData(channel));\n\n this.timeOverviews[channel].start(data);\n }\n\n break;\n }\n\n case 'time': {\n const interval = this.times[channel].param('interval');\n\n switch (this.times[channel].param('type')) {\n case 'uint': {\n const data = new Uint8Array(this.analysers[channel].fftSize);\n\n this.analysers[channel].getByteTimeDomainData(data);\n this.times[channel].start(data);\n\n break;\n }\n\n case 'float': {\n const data = new Float32Array(this.analysers[channel].fftSize);\n\n this.analysers[channel].getFloatTimeDomainData(data);\n this.times[channel].start(data);\n\n break;\n }\n }\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.timeDomainAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.timeDomainTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n\n case 'fft': {\n const interval = this.ffts[channel].param('interval');\n\n switch (this.ffts[channel].param('type')) {\n case 'uint': {\n const data = new Uint8Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getByteFrequencyData(data);\n this.ffts[channel].start(data);\n\n break;\n }\n\n case 'float': {\n const data = new Float32Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getFloatFrequencyData(data);\n this.ffts[channel].start(data, this.analysers[channel].minDecibels, this.analysers[channel].maxDecibels);\n\n break;\n }\n }\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.frequencyDomainAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.frequencyDomainTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n\n case 'spectrogram': {\n const interval = this.spectrograms[channel].param('interval');\n\n const data = new Uint8Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getByteFrequencyData(data);\n this.spectrograms[channel].start(data);\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.spectrogramAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.spectrogramTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method stops visualizer.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', 'spectrogram'.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {Analyser} Return value is for method chain.\n */\n public stop(domain: Domain, channelNumber?: ChannelNumber): Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n switch (domain) {\n case 'time': {\n const interval = this.times[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.timeDomainAnimationIds[channel];\n const timerId = this.timeDomainTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.timeDomainAnimationIds[channel]= null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.timeDomainTimerIds[channel]= null;\n }\n }\n\n break;\n }\n\n case 'fft': {\n const interval = this.ffts[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.frequencyDomainAnimationIds[channel];\n const timerId = this.frequencyDomainTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.frequencyDomainAnimationIds[channel] = null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.frequencyDomainTimerIds[channel] = null;\n }\n }\n\n break;\n }\n\n case 'spectrogram': {\n const interval = this.spectrograms[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.spectrogramAnimationIds[channel];\n const timerId = this.spectrogramTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.spectrogramAnimationIds[channel] = null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.spectrogramTimerIds[channel] = null;\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for analyser.\n * This method is overloaded for type interface and type check.\n * @param {keyof AnalyserParams|AnalyserParams} params This argument is string if getter. Otherwise, setter.\n * @return {AnalyserParams[keyof AnalyserParams]|Analyser} Return value is parameter for analyser if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'fftSize'): number;\n public param(params: 'frequencyBinCount'): number;\n public param(params: 'minDecibels'): number;\n public param(params: 'maxDecibels'): number;\n public param(params: 'smoothingTimeConstant'): number;\n public param(params: AnalyserParams): Analyser;\n public param(params: keyof AnalyserParams | AnalyserParams): AnalyserParams[keyof AnalyserParams] | Analyser {\n if (typeof params === 'string') {\n switch (params) {\n case 'fftSize': {\n return this.analysers[0].fftSize;\n }\n\n case 'frequencyBinCount': {\n return this.analysers[0].frequencyBinCount;\n }\n\n case 'minDecibels': {\n return this.analysers[0].minDecibels;\n }\n\n case 'maxDecibels': {\n return this.analysers[0].maxDecibels;\n }\n\n case 'smoothingTimeConstant': {\n return this.analysers[0].smoothingTimeConstant;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'fftSize': {\n this.analysers[0].fftSize = value;\n this.analysers[1].fftSize = value;\n break;\n }\n\n case 'minDecibels': {\n this.analysers[0].minDecibels = value;\n this.analysers[1].minDecibels = value;\n break;\n }\n\n case 'maxDecibels': {\n this.analysers[0].maxDecibels = value;\n this.analysers[1].maxDecibels = value;\n break;\n }\n\n case 'smoothingTimeConstant': {\n this.analysers[0].smoothingTimeConstant = value;\n this.analysers[1].smoothingTimeConstant = value;\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method selects domain for visualization.\n * This method is overloaded for type interface and type check.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', `spectrogram`.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {TimeOverview|Time|FFT|Analyser} Return value is instance of selected `Visualizer` class.\n */\n public domain(domain: 'timeoverview', channelNumber: ChannelNumber): TimeOverview;\n public domain(domain: 'time', channelNumber?: ChannelNumber): Time;\n public domain(domain: 'fft', channelNumber?: ChannelNumber): FFT;\n public domain(domain: 'spectrogram', channelNumber?: ChannelNumber): Spectrogram;\n public domain(domain: Domain, channelNumber?: ChannelNumber): TimeOverview | Time | FFT | Spectrogram | Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n switch (domain) {\n case 'timeoverview': {\n return this.timeOverviews[channel];\n }\n\n case 'time': {\n return this.times[channel];\n }\n\n case 'fft': {\n return this.ffts[channel];\n }\n\n case 'spectrogram': {\n return this.spectrograms[channel];\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AnalyserNode`.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {AnalyserNode}\n */\n public get(channelNumber?: ChannelNumber): AnalyserNode | null {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n return this.analysers[channel];\n }\n\n /** @override */\n public get INPUT(): GainNode {\n return this.input;\n }\n\n /** @override */\n public get OUTPUT(): GainNode {\n return this.input;\n }\n}\n","/**\n * This class is entity for recording frame.\n * Namely, this class has recorded sound data.\n */\nexport class Frame {\n private id: string;\n private dataBlocks: Float32Array[] = [];\n\n /**\n * @param {id} id This argument is frame ID.\n */\n constructor(id: string) {\n this.id = id;\n }\n\n /**\n * This method gets array that contains recorded sound data.\n * @return {Array<Float32Array>}\n */\n public get(): Float32Array[] {\n return this.dataBlocks;\n }\n\n /**\n * This method appends recorded sound data as `Float32Array`.\n * @param {Float32Array} dataBlock This argument is instance of `Float32Array` that has recorded sound data.\n * @return {Frame} Return value is for method chain.\n */\n public append(dataBlock: Float32Array): Frame {\n this.dataBlocks.push(dataBlock);\n return this;\n }\n\n /**\n * This method clears data blocks.\n */\n public clear(): void {\n this.dataBlocks.length = 0;\n }\n\n /**\n * This method determines whether contains recorded sound data.\n * @return {boolean} If frame has recorded data, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.dataBlocks.length > 0;\n }\n\n /** @override */\n public toString(): string {\n return this.id;\n }\n}\n","import type { Frame } from './Frame';\n\n/**\n * This class is entity for recording channel.\n */\nexport class Channel {\n private id: string;\n private frames: Frame[] = [];\n private channelGain = 1;\n\n /**\n * @param {string} id This argument is channel ID.\n */\n constructor(id: string) {\n this.id = id;\n }\n\n /**\n * This method appends instance of `Frame`.\n * @param {Frame} frame This argument is instance of `Frame` as recording frame.\n * @return {Channel} Return value is for method chain.\n */\n public append(frame: Frame): Channel {\n this.frames.push(frame);\n return this;\n }\n\n /**\n * This method gets designated frame or array that contains the all of frames.\n * This method is overloaded for type interface and type check.\n * @param {number} frameNumber This argument is target frame number.\n * @return {Frame|Array<Frame>}\n */\n public get(frameNumber: number): Frame;\n public get(): Frame[];\n public get(frameNumber?: number): Frame | Frame[] {\n if ((typeof frameNumber === 'number') && (frameNumber >= 0) && (frameNumber < this.frames.length)) {\n return this.frames[frameNumber];\n }\n\n return this.frames;\n }\n\n /**\n * This method gets or sets channel gain.\n * This method is overloaded for type interface and type check.\n * @param {number} param This argument is channel gain.\n * @return {number} Return value is channel gain.\n */\n public gain(): number;\n public gain(param: number): void;\n public gain(param?: number): number | void {\n if ((typeof param === 'number') && (param >= 0) && (param <= 1)) {\n this.channelGain = param;\n return;\n }\n\n return this.channelGain;\n }\n\n /**\n * This method gets the number of frames.\n * @return {number}\n */\n public length(): number {\n return this.frames.length;\n }\n\n /** @override */\n public toString(): string {\n return this.id;\n }\n}\n","import type { Inputs } from '../../worklet';\n\nimport { AudioWorkletProcessor } from '../../worklet';\n\nexport type RecorderProcessorMessageEventData = {\n inputs: Inputs\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method (sends input audio data to main thread) for recording audio.\n */\nexport class RecorderProcessor extends AudioWorkletProcessor {\n public static readonly BUFFER_SIZE = 128 as const;\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs): boolean {\n if ((inputs.length === 0) || (inputs[0].length === 0)) {\n return true;\n }\n\n const message: RecorderProcessorMessageEventData = { inputs };\n\n this.port.postMessage(message);\n\n return true;\n }\n}\n","import type { Connectable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { RecorderProcessorMessageEventData } from './RecorderProcessor';\n\nimport { Frame } from './Frame';\nimport { Channel } from './Channel';\nimport { RecorderProcessor } from './RecorderProcessor';\n\nexport type RecordType = 1 | 2; // Monaural | Stereo\nexport type QuantizationBit = 8 | 16;\nexport type WaveExportType = 'base64' | 'dataURL' | 'blob' | 'objectURL';\n\nexport type {\n Frame,\n Channel,\n RecorderProcessorMessageEventData\n};\n\nexport type RecorderParams = {\n '0'?: number,\n '1'?: number\n};\n\nexport { RecorderProcessor };\n\n/**\n * This private class is for multi track recording.\n */\nexport class Recorder implements Connectable {\n private processor: AudioWorkletNode;\n private sampleRate: number;\n private channels: Channel[] = [];\n private activeTrack = -1; // There is not any active track in case of -1\n private paused = true; // for preventing from duplicate `onaudioprocess` event (`start` method)\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.processor = new AudioWorkletNode(context, RecorderProcessor.name);\n this.sampleRate = context.sampleRate;\n\n this.processor.port.onmessage = (event: MessageEvent<RecorderProcessorMessageEventData>) => {\n if (this.activeTrack === -1) {\n return;\n }\n\n if (event.data.inputs.length === 0) {\n return;\n }\n\n const inputs = event.data.inputs[0];\n\n if (inputs.length === 0) {\n return;\n }\n\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\n\n if (inputs.length === 1) {\n const inputLs = inputs[0];\n const gainL = this.channels[0].gain();\n const frameL = this.channels[0].get(this.activeTrack);\n const recordedLs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n recordedLs[i] = gainL * inputLs[i];\n }\n\n frameL?.append(recordedLs);\n\n return;\n }\n\n const inputLs = inputs[0];\n const inputRs = inputs[1];\n\n const gainL = this.channels[0].gain();\n const gainR = this.channels[1].gain();\n\n const frameL = this.channels[0].get(this.activeTrack);\n const frameR = this.channels[1].get(this.activeTrack);\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 frameL?.append(recordedLs);\n frameR?.append(recordedRs);\n };\n }\n\n /**\n * This method sets the max number of track.\n * @param {RecordType} numberOfChannels This argument is the number of channels (not used currently).\n * @param {number} numberOfTracks This argument is the max number of tracks.\n * @return {Recorder} Return value is for method chain.\n */\n public setup(numberOfChannels: RecordType, numberOfTracks: number): Recorder {\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 < numberOfTracks; i++) {\n channel.append(new Frame(i.toString(10)));\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 * If there is not designated track number, active track number is -1.\n * @return {Recorder} Return value is for method chain.\n */\n public ready(trackNumber: number): Recorder {\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 sound recording. If there is not any active track, this method stops `onaudioprocess` event handler.\n * @return {Recorder} Return value is for method chain.\n */\n public start(): Recorder {\n if ((this.activeTrack === -1) || !this.paused) {\n return this;\n }\n\n this.paused = false;\n\n return this;\n }\n\n /**\n * This method turns off active track, and stops `onaudioprocess` event handler.\n * @return {Recorder} Return value is for method chain.\n */\n public stop(): Recorder {\n this.activeTrack = -1; // Flag becomes inactive\n this.paused = true;\n\n this.processor.disconnect(0);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for recorder.\n * This method is overloaded for type interface and type check.\n * @param {keyof RecorderParams|RecorderParams} params This argument is string if getter. Otherwise, setter.\n * @return {RecorderParams[keyof RecorderParams]|Recorder} Return value is parameter for recorder if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: '0' | '1'): number;\n public param(params: RecorderParams): Recorder;\n public param(params: keyof RecorderParams | RecorderParams): RecorderParams[keyof RecorderParams] | Recorder {\n if (typeof params === 'string') {\n switch (params) {\n case '0': {\n if (this.channels[0]) {\n return this.channels[0].gain();\n }\n\n break;\n }\n\n case '1': {\n if (this.channels[1]) {\n return this.channels[1].gain();\n }\n\n break;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case '0': {\n if (this.channels[0] && (typeof value === 'number')) {\n this.channels[0].gain(value);\n }\n\n break;\n }\n\n case '1': {\n if (this.channels[1] && (typeof value === 'number')) {\n this.channels[1].gain(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method determines whether active track exists.\n * @return {number} Return value is active track number.\n */\n public get(): number {\n return this.activeTrack;\n }\n\n /**\n * This method clears record track.\n * @param {number} trackNumber This argument is track for clearing. If this argument is -1, target is the all of tracks.\n * @return {Recorder} Return value is for method chain.\n */\n public clear(trackNumber: number): Recorder {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n if (trackNumber === -1) {\n for (const channel of this.channels) {\n const frames = channel.get();\n\n for (const frame of frames) {\n frame.clear();\n }\n }\n } else {\n if (this.hasTrack(trackNumber)) {\n for (const channel of this.channels) {\n const frame = channel.get(trackNumber);\n\n frame?.clear();\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method creates WAVE file as one of Base64, Data URL, Blob, Object URL.\n * @param {number} trackNumber This argument is track number for mixing. If this argument is -1, target is the all of tracks.\n * @param {RecordType} numberOfChannels This argument is in order to select monaural or stereo.\n * @param {QuantizationBit} qbits This argument is quantization bit for PCM.\n * @param {WaveExportType} type This argument is one of 'base64', 'dataURL', 'blob', 'objectURL'.\n * @return {string|Blob} Return value is one of Base64, Data URL, Blob, Object URL as WAVE file.\n */\n public create(trackNumber: number, numberOfChannels: RecordType, qbits: QuantizationBit, type: WaveExportType): string | Blob {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n let soundLs: Float32Array | null = null;\n let soundRs: Float32Array | null = null;\n\n if ((trackNumber === -1) && this.has(-1, -1)) {\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 if ((soundLs === null) || (soundRs === null)) {\n return '';\n }\n\n // PCM parameters\n const RATE = this.sampleRate;\n const QBITS = qbits;\n const CHANNELS = numberOfChannels;\n\n // Parameters for WAVE file\n\n // the number of total samples in entire channels\n const SAMPLES = CHANNELS * Math.min(soundLs.length, soundRs.length);\n\n // chunk ID size + chunk data size\n const CHUNK_SIZE = 4 + 4;\n\n // 1 byte * 4 ('W', 'A', 'V', 'E')\n const FORM_TYPE_ID_SIZE = 4;\n\n // 16 bytes (Format Tag size + Channels size + Sample rate size + BPS size + Block size + Bits per sample size)\n // (+ 2 bytes if Non-PCM)\n // (+ 24 bytes if extensible WAVE (ExWAVE))\n const FMT_CHUNK_SIZE = CHUNK_SIZE + 16;\n\n const DATA_CHUNK_SIZE = CHUNK_SIZE + (SAMPLES * (QBITS / 8));\n\n // WAVE file size\n const SIZE = CHUNK_SIZE + FORM_TYPE_ID_SIZE + FMT_CHUNK_SIZE + DATA_CHUNK_SIZE;\n\n // total size - (RIFF chunk ID size + Form type ID size)\n const RIFF_CHUNK_SIZE = SIZE - (4 + 4);\n\n const BPS = RATE * CHANNELS * (QBITS / 8);\n\n const DATA_SIZE = SAMPLES * (QBITS / 8);\n\n let sounds: Uint8Array | Int16Array | null = null;\n\n switch (QBITS) {\n case 8: {\n sounds = new Uint8Array(SAMPLES);\n\n for (let i = 0; i < SAMPLES; i++) {\n // Convert to 8 bits unsigned integer (-1 -> 0, 0 -> 128, 1 -> 255)\n let binary = 0;\n\n if ((i % CHANNELS) === 0) {\n binary = Math.round(((soundLs[Math.trunc(i / CHANNELS)] + 1) / 2) * ((2 ** 8) - 1)); // Left channel\n } else {\n binary = Math.round(((soundRs[Math.trunc(i / CHANNELS)] + 1) / 2) * ((2 ** 8) - 1)); // Right channel\n }\n\n // for preventing from clipping\n if (binary > ((2 ** 8) - 1)) { binary = ((2 ** 8) - 1); }\n if (binary < ((2 ** 0) - 1)) { binary = ((2 ** 0) - 1); }\n\n sounds[i] = binary;\n }\n\n break;\n }\n\n case 16: {\n sounds = new Int16Array(SAMPLES);\n\n for (let i = 0; i < SAMPLES; i++) {\n // Convert to 16 bits signed integer (-1 -> -32768, 0 -> 0, 1 -> 32767)\n let binary = 0;\n\n if ((i % CHANNELS) === 0) {\n binary = Math.round(soundLs[Math.trunc(i / CHANNELS)] * (2 ** 15)); // Left channel\n } else {\n binary = Math.round(soundRs[Math.trunc(i / CHANNELS)] * (2 ** 15)); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (+(2 ** 15) - 1)) { binary = +(2 ** 15) - 1; }\n if (binary < (-(2 ** 15) - 0)) { binary = -(2 ** 15) - 0; }\n\n sounds[i] = binary;\n }\n\n break;\n }\n }\n\n if (sounds === null) {\n return '';\n }\n\n // Byte order is little endian\n const wave = new Uint8Array(SIZE);\n\n // RIFF chunk\n\n // chunk ID\n wave[0] = 0x52; // 'R'\n wave[1] = 0x49; // 'I'\n wave[2] = 0x46; // 'F'\n wave[3] = 0x46; // 'F'\n\n // chunk data size\n wave[4] = (RIFF_CHUNK_SIZE >> 0) & 0xFF;\n wave[5] = (RIFF_CHUNK_SIZE >> 8) & 0xFF;\n wave[6] = (RIFF_CHUNK_SIZE >> 16) & 0xFF;\n wave[7] = (RIFF_CHUNK_SIZE >> 24) & 0xFF;\n\n // Form type ID\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\n // chunk ID\n wave[12] = 0x66; // 'f'\n wave[13] = 0x6D; // 'm'\n wave[14] = 0x74; // 't'\n wave[15] = 0x20; // ' '\n\n // chunk data size\n wave[16] = 16;\n wave[17] = 0;\n wave[18] = 0;\n wave[19] = 0;\n\n // Format Tag\n // 1: PCM (Pulse Code Modulation)\n // 2: MS ADPCM (Adaptive Differential PCM)\n // 6: A-law\n // 7: μ-law\n // ... etc\n wave[20] = 1;\n wave[21] = 0;\n\n // Channels\n // 1: Monaural\n // 2: Stereo\n wave[22] = CHANNELS;\n wave[23] = 0;\n\n // 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 // (Average) Bytes 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 // Block size\n wave[32] = CHANNELS * (QBITS / 8);\n wave[33] = 0;\n\n // Bits per sample\n wave[34] = QBITS;\n wave[35] = 0;\n\n // data chunk\n\n // chunk ID\n wave[36] = 0x64; // 'd'\n wave[37] = 0x61; // 'a'\n wave[38] = 0x74; // 't\n wave[39] = 0x61; // 'a'\n\n // chunk data size\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 // PCM data\n for (let i = 0; i < SAMPLES; i++) {\n const offset = SIZE - DATA_SIZE;\n\n switch (QBITS) {\n case 8: {\n wave[offset + i] = sounds[i];\n break;\n }\n\n case 16: {\n wave[offset + (2 * i) + 0] = ((sounds[i] >> 0) & 0x00FF);\n wave[offset + (2 * i) + 1] = ((sounds[i] >> 8) & 0x00FF);\n break;\n }\n }\n }\n\n // Create WAVE file (as one of Base64, Data URL, Blob, Object URL)\n switch (type) {\n case 'base64' :\n case 'dataURL': {\n const base64 = window.btoa(Array.from(wave).map((d: number) => String.fromCodePoint(d)).join(''));\n\n if (type === 'base64') {\n return base64;\n }\n\n return `data:audio/wav;base64,${base64}`;\n }\n\n case 'blob' :\n case 'objectURL': {\n const blob = new Blob([wave], { type: 'audio/wav' });\n\n if (type === 'blob') {\n return blob;\n }\n\n return window.URL.createObjectURL(blob);\n }\n }\n }\n\n /**\n * This method determines whether track has recorded data.\n * @param {ChanneNumber} channelNumber This argument is target channel number (if this argument is -1, target is the all of channels).\n * @param {number} trackNumber This argument is target track number (if this argument is -1, target is the all of tracks).\n * @return {boolean} If there is track that has recorded data at least, this method returns `true`. Otherwise this value is `false`.\n */\n public has(channelNumber: ChannelNumber, trackNumber: number): boolean {\n if (!this.hasChannel(channelNumber)) {\n return this.channels.some((channel: Channel) => {\n const frames = channel.get();\n\n return frames.some((frame: Frame) => frame.has());\n });\n }\n\n const frames = this.channels[channelNumber].get();\n\n if (!this.hasTrack(trackNumber)) {\n return frames.some((frame: Frame) => frame.has());\n }\n\n const frame = this.channels[channelNumber].get(trackNumber);\n\n return frame?.has() ?? false;\n }\n\n /**\n * This method determines whether designated channel number is valid.\n * @param {ChanneNumber} channelNumber This argument is channel number for validation.\n * @return {boolean} If designated channel is valid, this value is `true`. Otherwise, this value is `false`.\n */\n public hasChannel(channelNumber: ChannelNumber): boolean {\n return (channelNumber >= 0) && (channelNumber < this.channels.length);\n }\n\n /**\n * This method determines whether designated track number is valid.\n * @param {number} trackNumber This argument is track number for validation.\n * @return {boolean} If designated track is valid, this value is `true`. Otherwise, this value is `false`.\n */\n public hasTrack(trackNumber: number): boolean {\n return (trackNumber >= 0) && this.channels.every((channel: Channel) => trackNumber < channel.length());\n }\n\n /** @override */\n public get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public get OUTPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /**\n * This method flats recorded sound data (data block of `Float32Array`) that track contains.\n * @param {ChanneNumber} channelNumber This argument is channel number for mixing.\n * @param {number} trackNumber This argument is track number.\n * @return {Float32Array} Return value is instance of `Float32Array` that contains flatten sound data.\n */\n private flatTrack(channelNumber: ChannelNumber, trackNumber: number): Float32Array | null {\n if (!this.hasChannel(channelNumber) || !this.hasTrack(trackNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const frame = channel.get(trackNumber);\n\n if (frame === null) {\n return null;\n }\n\n const dataBlocks = frame.get();\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\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 sound data that plural track contains.\n * @param {ChannelNumber} channelNumber This argument is channel number for mixing.\n * @return {Float32Array} Return value is instance of `Float32Array` that contains synthesized sound data.\n */\n private mixTrack(channelNumber: ChannelNumber): Float32Array | null {\n if (!this.hasChannel(channelNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const frames = channel.get();\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\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 frame\n for (const frame of frames) {\n const dataBlocks = frame.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 currentFrame = 0, len = frames.length; currentFrame < len; currentFrame++) {\n const frame = frames[currentFrame];\n const dataBlocks = frame.get();\n const dataBlock = dataBlocks[currentBlock];\n\n if (dataBlock && ((index >= 0) && (index <= dataBlock.length))) {\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 data block of `Float32Array`\n currentBlock++;\n index = 0;\n }\n }\n }\n}\n","import type { Connectable, Statable } from '../../interfaces';\n\n/**\n * This class is superclass for effector classes.\n * Also, this class is used for implementing custom effector.\n */\nexport abstract class Effector implements Connectable, Statable {\n protected context: AudioContext;\n protected input: GainNode;\n protected output: GainNode;\n\n protected lfo: OscillatorNode;\n protected depth: GainNode;\n protected rate: AudioParam;\n\n protected isActive = true;\n protected paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n\n // for connecting external modules\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 }\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 */\n public start(startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.lfo.start(startTime ?? this.context.currentTime);\n this.paused = false;\n }\n\n /**\n * This method stops LFO, then creates 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 */\n public stop(stopTime?: number, releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n // Store parameters\n const type = this.lfo.type;\n const rate = this.lfo.frequency.value;\n\n // Destroy instance of `OscillatorNode`\n this.lfo.stop((stopTime ?? this.context.currentTime) + (releaseTime ?? 0));\n\n // Create instance of `OscillatorNode` again\n this.lfo = this.context.createOscillator();\n\n // Restore parameters\n this.lfo.type = type;\n this.lfo.frequency.value = rate;\n\n this.rate = this.lfo.frequency;\n\n this.paused = true;\n }\n\n /**\n * This method connects `AudioNode`s for effector.\n * @return {GainNode} Return value is for `connect` method chain.\n */\n public abstract connect(): GainNode;\n\n /**\n * This method gets effector's parameters as associative array.\n */\n public abstract params(): void;\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * This method gets effector state. If returns `true`, effector is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates effector.\n * @return {Effector} Return value is for method chain.\n */\n public activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Start LFO\n this.start(0);\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method deactivates effector.\n * @return {Effector} Return value is for method chain.\n */\n public deactivate() {\n // Stop LFO\n this.stop(0);\n\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * Connector for input.\n */\n public get INPUT(): GainNode {\n return this.input;\n }\n\n /**\n * Connector for output.\n */\n public get OUTPUT(): GainNode {\n return this.output;\n }\n}\n","import { Effector } from './Effector';\n\nexport type AutopannerParams = {\n state?: boolean,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Autopanner.\n */\nexport class Autopanner extends Effector {\n private panner: StereoPannerNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.panner = this.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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect again\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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.output;\n }\n\n /**\n * This method gets or sets parameters for autopanner effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof AutopannerParams|AutopannerParams} params This argument is string if getter. Otherwise, setter.\n * @return {AutopannerParams[keyof AutopannerParams]|Autopanner} Return value is parameter for autopanner effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: AutopannerParams): Autopanner;\n public param(params: keyof AutopannerParams | AutopannerParams): AutopannerParams[keyof AutopannerParams] | Autopanner {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<AutopannerParams> {\n return {\n state: this.isActive,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type BitCrusherParams = {\n state?: boolean,\n bits?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for BitCrusher.\n */\nexport class BitCrusher extends Effector {\n private shaper: WaveShaperNode;\n private inputShaper: WaveShaperNode;\n private outputShaper: WaveShaperNode;\n private inputLevel: GainNode;\n private outputLevel: GainNode;\n private bitsInput: ConstantSourceNode;\n private bitsGain: GainNode;\n\n private bits = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = this.context.createWaveShaper();\n this.inputShaper = this.context.createWaveShaper();\n this.outputShaper = this.context.createWaveShaper();\n\n this.inputLevel = this.context.createGain();\n this.outputLevel = this.context.createGain();\n\n this.bitsInput = this.context.createConstantSource();\n this.bitsGain = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1023);\n\n for (let i = 0; i < 512; i++) {\n const v = (((i / 512) * 128) | 0) / 128;\n\n curve[511 + i] = v;\n curve[511 - i] = -v;\n }\n\n const inputCurve = new Float32Array(10);\n const outputCurve = new Float32Array(10);\n\n for (let i = 0, d = 64; i < 6; i++, d *= 0.5) {\n inputCurve[0 + i] = 1 / 64;\n inputCurve[4 + i] = 1 / d;\n\n outputCurve[0 + i] = 64;\n outputCurve[4 + i] = d;\n }\n\n this.shaper.curve = curve;\n this.shaper.oversample = '4x';\n this.inputShaper.curve = inputCurve;\n this.outputShaper.curve = outputCurve;\n\n this.inputLevel.gain.value = 0;\n this.outputLevel.gain.value = 0;\n\n this.bitsInput.offset.value = this.bits;\n this.bitsGain.gain.value = 1 / 8;\n\n // `BitCrusher` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.bitsInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.bitsInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.bitsInput = this.context.createConstantSource();\n\n // Restore parameters\n this.bitsInput.offset.value = this.bits;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.shaper.disconnect(0);\n this.inputShaper.disconnect(0);\n this.outputShaper.disconnect(0);\n this.inputLevel.disconnect(0);\n this.outputLevel.disconnect(0);\n this.bitsInput.disconnect(0);\n this.bitsGain.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Input Gain) -> WaveShaperNode (Bit Crusher) -> GainNode (Output Gain) -> GainNode (Output)\n this.input.connect(this.inputLevel);\n this.inputLevel.connect(this.shaper);\n this.shaper.connect(this.outputLevel);\n this.outputLevel.connect(this.output);\n\n // ConstantSourceNode (Input as Bit Crusher) -> GainNode (Bit Crusher Gain)\n this.bitsInput.connect(this.bitsGain);\n\n // GainNode (Bit Crusher Gain) -> WaveShaperNode (Input Envelope Follower) -> AudioParam (gain as input)\n this.bitsGain.connect(this.inputShaper);\n this.inputShaper.connect(this.inputLevel.gain);\n\n // GainNode (Bit Crusher Gain) -> WaveShaperNode (Output Envelope Follower) -> AudioParam (gain as output)\n this.bitsGain.connect(this.outputShaper);\n this.outputShaper.connect(this.outputLevel.gain);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for bit crusher effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof BitCrusherParams|BitCrusherParams} params This argument is string if getter. Otherwise, setter.\n * @return {BitCrusherParams[keyof BitCrusherParams]|BitCrusher} Return value is parameter for bit crusher effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'bits'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: BitCrusherParams): BitCrusher;\n public param(params: keyof BitCrusherParams | BitCrusherParams): BitCrusherParams[keyof BitCrusherParams] | BitCrusher {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'bits': {\n return this.bits;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'bits': {\n if (typeof value === 'number') {\n this.bits = value;\n this.bitsInput.offset.value = this.bits;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<BitCrusherParams> {\n return {\n state : this.isActive,\n bits : this.bits,\n oversample: this.shaper.oversample\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type ChorusParams = {\n state?: boolean,\n time?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Chorus.\n */\nexport class Chorus extends Effector {\n private delay: DelayNode;\n private tone: BiquadFilterNode;\n private dry: GainNode;\n private wet: GainNode;\n private feedback: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.delay = context.createDelay();\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.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = 'lowpass';\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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode's again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for chorus effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof ChorusParams|ChorusParams} params This argument is string if getter. Otherwise, setter.\n * @return {ChorusParams[keyof ChorusParams]|Chorus} Return value is parameter for chorus effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: ChorusParams): Chorus;\n public param(params: keyof ChorusParams | ChorusParams): ChorusParams[keyof ChorusParams] | Chorus {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.delay.delayTime.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<ChorusParams> {\n return {\n state : this.isActive,\n time : this.delay.delayTime.value,\n depth : this.depthRate,\n rate : this.rate.value,\n mix : this.wet.gain.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}\n","import { Effector } from './Effector';\n\nexport type CompressorParams = {\n state?: boolean,\n threshold?: number,\n knee?: number,\n ratio?: number,\n attack?: number,\n release?: number\n};\n\n/**\n * Effector's subclass for Compressor.\n */\nexport class Compressor extends Effector {\n private compressor: DynamicsCompressorNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.compressor = context.createDynamicsCompressor();\n\n // Initialize parameters\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.activate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Compressor) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for compressor.\n * This method is overloaded for type interface and type check.\n * @param {keyof CompressorParams|CompressorParams} params This argument is string if getter. Otherwise, setter.\n * @return {CompressorParams[keyof CompressorParams]|Compressor} Return value is parameter for compressor if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'threshold'): number;\n public param(params: 'knee'): number;\n public param(params: 'ratio'): number;\n public param(params: 'attack'): number;\n public param(params: 'release'): number;\n public param(params: CompressorParams): Compressor;\n public param(params: keyof CompressorParams | CompressorParams): CompressorParams[keyof CompressorParams] | Compressor {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'threshold': {\n return this.compressor.threshold.value;\n }\n\n case 'knee': {\n return this.compressor.knee.value;\n }\n\n case 'ratio': {\n return this.compressor.ratio.value;\n }\n\n case 'attack': {\n return this.compressor.attack.value;\n }\n\n case 'release': {\n return this.compressor.release.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.compressor.threshold.value = value;\n }\n\n break;\n }\n\n case 'knee': {\n if (typeof value === 'number') {\n this.compressor.knee.value = value;\n }\n\n break;\n }\n\n case 'ratio': {\n if (typeof value === 'number') {\n this.compressor.ratio.value = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.compressor.attack.value = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.compressor.release.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<CompressorParams> {\n return {\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}\n","import { Effector } from './Effector';\n\nexport type DelayParams = {\n state?: boolean,\n time?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Delay.\n */\nexport class Delay extends Effector {\n public static MAX_DELAY_TIME = 5; // Max delay time is 5000 [ms]\n\n private delay: DelayNode;\n private dry: GainNode;\n private wet: GainNode;\n private tone: BiquadFilterNode;\n private feedback: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\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 = 'lowpass';\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for delay effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof DelayParams|DelayParams} params This argument is string if getter. Otherwise, setter.\n * @return {DelayParams[keyof DelayParams]|Delay} Return value is parameter for delay effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: DelayParams): Delay;\n public param(params: keyof DelayParams | DelayParams): DelayParams[keyof DelayParams] | Delay {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<DelayParams> {\n return {\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}\n","import type { Statable } from '../../interfaces';\n\nexport type EnvelopeGeneratorParams = {\n state?: boolean,\n attack?: number,\n decay?: number,\n sustain?: number,\n release?: number\n};\n\n/**\n * This private class is for Envelope Generator.\n */\nexport class EnvelopeGenerator implements Statable {\n public static MIN_GAIN = 1e-3;\n\n private context: AudioContext;\n private generators: GainNode[] = [];\n private activeIndexes: number[] = [];\n private activeCounter = 0;\n\n private attack = 0.01;\n private decay = 0.3;\n private sustain = 0.5;\n private release = 1.0;\n\n private isActive = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n }\n\n /**\n * This method connects instance of `AudioNode`.\n * @param {number} index This argument is in order to select instance of `GainNode` that is Envelope Generator.\n * @param {AudioNode} input This argument is instance of `AudioNode` as input.\n * @param {AudioNode} output This argument is instance of `AudioNode` as output.\n */\n public ready(index: number, input: AudioNode | null, output: AudioNode | null): void {\n if (input && output && this.generators[index]) {\n input.connect(this.generators[index]);\n this.generators[index].connect(output);\n } else if (input && (output === null) && this.generators[index]) {\n input.connect(this.generators[index]);\n } else if ((input === null) && output && this.generators[index]) {\n this.generators[index].connect(output);\n }\n\n this.activeIndexes[index] = index;\n this.activeCounter++;\n }\n\n /**\n * This method changes gain (Attack -> Decay -> Sustain).\n * @param {number} startTime This argument is start time of Attack.\n */\n public start(startTime: number): void {\n // Attack -> Decay -> Sustain\n const t0 = startTime;\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 if (!this.isActive) {\n this.generators[activeIndex].gain.value = 1;\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\n /**\n * This method changes gain (Attack or Decay or Sustain -> Release).\n * @param {number} stopTime This argument is start time of Release.\n * @param {boolean} useCurve This argument is to use different methods. The default value is `false`.\n */\n public stop(stopTime: number, useCurve?: boolean): void {\n const s = stopTime - this.release;\n\n // Sustain -> Release\n const t3 = s >= this.context.currentTime ? s : this.context.currentTime;\n const t4 = this.release;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n if (!this.isActive) {\n this.generators[activeIndex].gain.value = 0;\n continue;\n }\n\n // in case of mouseup on the way of Decay\n if (typeof this.generators[activeIndex].gain.cancelAndHoldAtTime === 'function') {\n this.generators[activeIndex].gain.cancelAndHoldAtTime(t3);\n } else {\n const value = this.generators[activeIndex].gain.value;\n\n this.generators[activeIndex].gain.cancelScheduledValues(t3);\n this.generators[activeIndex].gain.setValueAtTime(value, t3);\n }\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\n /**\n * This method gets or sets parameters for envelope generator.\n * This method is overloaded for type interface and type check.\n * @param {keyof EnvelopeGeneratorParams|EnvelopeGeneratorParams} params This argument is string if getter. Otherwise, setter.\n * @return {EnvelopeGeneratorParams[keyof EnvelopeGeneratorParams]|EnvelopeGenerator} Return value is parameter for envelope generator if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'attack'): number;\n public param(params: 'decay'): number;\n public param(params: 'sustain'): number;\n public param(params: 'release'): number;\n public param(params: EnvelopeGeneratorParams): EnvelopeGenerator;\n public param(params: keyof EnvelopeGeneratorParams | EnvelopeGeneratorParams): EnvelopeGeneratorParams[keyof EnvelopeGeneratorParams] | EnvelopeGenerator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'attack': {\n return this.attack;\n }\n\n case 'decay': {\n return this.decay;\n }\n\n case 'sustain': {\n return this.sustain;\n }\n\n case 'release': {\n return this.release;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.attack = value;\n }\n\n break;\n }\n\n case 'decay': {\n if (typeof value === 'number') {\n this.decay = value;\n }\n\n break;\n }\n\n case 'sustain': {\n if (typeof value === 'number') {\n this.sustain = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.release = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is index of array that contains instance of `GainNode` for Envelope Generator.\n * @return {GainNode} This is returned as instance of `GainNode` for Envelope Generator.\n */\n public getGenerator(index: number): GainNode | null {\n if ((index >= 0) && (index < this.generators.length)) {\n return this.generators[index];\n }\n\n return null;\n }\n\n /**\n * This method sets instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is index of array that contains instance of `GainNode` for Envelope Generator.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n public setGenerator(index: number): void {\n this.generators[index] = this.context.createGain();\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 public paused(): boolean {\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 return false;\n }\n\n /**\n * This method clears variables for managing instance of `GainNode`.\n * @param {boolean} disconnected This argument is in order to determine whether disconnect `AudioNode`.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n public clear(disconnected: boolean): void {\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 (disconnected) {\n generator.disconnect(0);\n }\n }\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {EnvelopeGeneratorParams}\n */\n public params(): Required<EnvelopeGeneratorParams> {\n return {\n state : this.isActive,\n attack : this.attack,\n decay : this.decay,\n sustain: this.sustain,\n release: this.release\n };\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * This method gets envelope generator state. If returns `true`, envelope generator is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates envelope generator.\n * @return {EnvelopeGenerator} Return value is for method chain.\n */\n public activate(): EnvelopeGenerator {\n this.isActive = true;\n return this;\n }\n\n /**\n * This method deactivates envelope generator.\n * @return {EnvelopeGenerator} Return value is for method chain.\n */\n public deactivate(): EnvelopeGenerator {\n this.isActive = false;\n return this;\n }\n}\n","import { Effector } from './Effector';\n\nexport type EqualizerParams = {\n state?: boolean,\n bass?: number,\n middle?: number,\n treble?: number,\n presence?: number\n};\n\n/**\n * Effector's subclass for Equalizer.\n */\nexport class Equalizer extends Effector {\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n private presence: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n **/\n constructor(context: AudioContext) {\n super(context);\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n this.presence = context.createBiquadFilter();\n\n // Initialize parameters\n\n // Set filter type\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n this.presence.type = 'highshelf';\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; // Not used\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: Peaking) -> BiquadFilterNode (Presence: High-shelving) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof EqualizerParams|EqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {EqualizerParams[keyof EqualizerParams]|Equalizer} Return value is parameter for equalizer if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'presence'): number;\n public param(params: EqualizerParams): Equalizer;\n public param(params: keyof EqualizerParams | EqualizerParams): EqualizerParams[keyof EqualizerParams] | Equalizer {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'presence': {\n return this.presence.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'presence': {\n if (typeof value === 'number') {\n this.presence.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<EqualizerParams> {\n return {\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}\n","import { Effector } from './Effector';\n\nexport type FilterParams = {\n state?: boolean,\n type?: BiquadFilterType,\n frequency?: number,\n Q?: number,\n gain?: number,\n range?: number,\n attack?: number,\n decay?: number,\n sustain?: number,\n release?: number\n};\n\n/**\n * Effector's subclass for Filter.\n */\nexport class Filter extends Effector {\n private filter: BiquadFilterNode;\n\n private maxFrequency: number;\n private range = 0.1; // 10% -> between `maxFrequency * 0.1` and `maxFrequency`\n\n private attack = 0.01;\n private decay = 0.3;\n private sustain = 1.0;\n private release = 1.0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.filter = context.createBiquadFilter();\n\n // Initialize parameters\n this.filter.type = 'lowpass';\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\n // `Filter` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(startTime?: number): void {\n if (!this.isActive) {\n return;\n }\n\n const t0 = startTime ?? this.context.currentTime;\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 /** @override */\n public override stop(stopTime?: number): void {\n if (!this.isActive) {\n return;\n }\n\n const t3 = stopTime ?? this.context.currentTime;\n const t4 = this.release;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n if (typeof this.filter.frequency.cancelAndHoldAtTime === 'function') {\n this.filter.frequency.cancelAndHoldAtTime(t3);\n } else {\n const value = this.filter.frequency.value;\n\n this.filter.frequency.cancelScheduledValues(t3);\n this.filter.frequency.setValueAtTime(value, t3);\n }\n\n this.filter.frequency.setTargetAtTime(minFrequnecy, t3, t4); // Sustain -> Release\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Filter) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for filter effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FilterParams|FilterParams} params This argument is string if getter. Otherwise, setter.\n * @return {FilterParams[keyof FilterParams]|Filter} Return value is parameter for filter effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): BiquadFilterType;\n public param(params: 'frequency'): number;\n public param(params: 'Q'): number;\n public param(params: 'gain'): number;\n public param(params: 'range'): number;\n public param(params: 'attack'): number;\n public param(params: 'decay'): number;\n public param(params: 'sustain'): number;\n public param(params: 'release'): number;\n public param(params: FilterParams): Filter;\n public param(params: keyof FilterParams | FilterParams): FilterParams[keyof FilterParams] | Filter {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.filter.type;\n }\n\n case 'frequency': {\n return this.filter.frequency.value;\n }\n\n case 'Q': {\n return this.filter.Q.value;\n }\n\n case 'gain': {\n return this.filter.gain.value;\n }\n\n case 'range': {\n return this.range;\n }\n\n case 'attack': {\n return this.attack;\n }\n\n case 'decay': {\n return this.decay;\n }\n\n case 'sustain': {\n return this.sustain;\n }\n\n case 'release': {\n return this.release;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.filter.type = value;\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n this.filter.frequency.value = value;\n this.maxFrequency = value;\n }\n\n break;\n }\n\n case 'Q': {\n if (typeof value === 'number') {\n this.filter.Q.value = value;\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.filter.gain.value = value;\n }\n\n break;\n }\n\n case 'range': {\n if (typeof value === 'number') {\n this.range = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.attack = value;\n }\n\n break;\n }\n\n case 'decay': {\n if (typeof value === 'number') {\n this.decay = value;\n }\n\n break;\n }\n\n case 'sustain': {\n if (typeof value === 'number') {\n this.sustain = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.release = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FilterParams> {\n return {\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\n /** @override */\n public override activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /** @override */\n public override deactivate() {\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n}\n","import { Effector } from './Effector';\n\nexport type FlangerParams = {\n state?: boolean,\n time?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Flanger.\n */\nexport class Flanger extends Effector {\n private delay: DelayNode;\n private tone: BiquadFilterNode;\n private dry: GainNode;\n private wet: GainNode;\n private feedback: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.delay = context.createDelay();\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.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = 'lowpass';\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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for flanger effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FlangerParams|FlangerParams} params This argument is string if getter. Otherwise, setter.\n * @return {FlangerParams[keyof FlangerParams]|Flanger} Return value is parameter for flanger effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: FlangerParams): Flanger;\n public param(params: keyof FlangerParams | FlangerParams): FlangerParams[keyof FlangerParams] | Flanger {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.delay.delayTime.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FlangerParams> {\n return {\n state : this.isActive,\n time : this.delay.delayTime.value,\n depth : this.depthRate,\n rate : this.rate.value,\n mix : this.wet.gain.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}\n","import { Effector } from './Effector';\n\nexport type FuzzParams = {\n state?: boolean,\n drive?: number,\n level?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for Fuzz.\n */\nexport class Fuzz extends Effector {\n private positiveShaper: WaveShaperNode;\n private negativeShaper: WaveShaperNode;\n private positiveInputGain: GainNode;\n private negativeInputGain: GainNode;\n private positiveOutputGain: GainNode;\n private negativeOutputGain: GainNode;\n private outFilter: BiquadFilterNode;\n private driveInput: ConstantSourceNode;\n private level: GainNode;\n\n private drive = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.positiveShaper = this.context.createWaveShaper();\n this.negativeShaper = this.context.createWaveShaper();\n this.positiveInputGain = this.context.createGain();\n this.negativeInputGain = this.context.createGain();\n this.positiveOutputGain = this.context.createGain();\n this.negativeOutputGain = this.context.createGain();\n\n this.driveInput = this.context.createConstantSource();\n\n this.outFilter = this.context.createBiquadFilter();\n\n this.level = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1024);\n\n for (let i = 0; i < 512; i++) {\n const r = Math.tanh((4 * i) / 512) * 0.5;\n const v = 1 - (i / 512);\n\n curve[512 + i] = r;\n curve[511 - i] = r * (v ** 4);\n }\n\n this.positiveShaper.curve = curve;\n this.negativeShaper.curve = curve;\n\n this.positiveShaper.oversample = '4x';\n this.negativeShaper.oversample = '4x';\n\n this.positiveInputGain.gain.value = 1;\n this.negativeInputGain.gain.value = -1;\n\n this.positiveOutputGain.gain.value = 1;\n this.negativeOutputGain.gain.value = -1;\n\n this.driveInput.offset.value = this.drive;\n\n this.outFilter.type = 'highpass';\n this.outFilter.frequency.value = 80;\n this.outFilter.Q.value = 1;\n this.outFilter.gain.value = 0;\n\n this.level.gain.value = 1;\n\n // `Fuzz` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.driveInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.driveInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.driveInput = this.context.createConstantSource();\n\n // Restore parameters\n this.driveInput.offset.value = this.drive;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.positiveShaper.disconnect(0);\n this.negativeShaper.disconnect(0);\n this.positiveInputGain.disconnect(0);\n this.negativeInputGain.disconnect(0);\n this.positiveOutputGain.disconnect(0);\n this.negativeOutputGain.disconnect(0);\n this.driveInput.disconnect(0);\n this.outFilter.disconnect(0);\n this.level.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Positive Input Gain) -> WaveShaperNode (+Fuzz) -> GainNode (Positive Output Gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.positiveInputGain);\n this.positiveInputGain.connect(this.positiveShaper);\n this.positiveShaper.connect(this.positiveOutputGain);\n this.positiveOutputGain.connect(this.outFilter);\n\n // GainNode (Input) > GainNode (Negative Input Gain) -> WaveShaperNode (-Fuzz) -> GainNode (Negative Output Gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.negativeInputGain);\n this.negativeInputGain.connect(this.negativeShaper);\n this.negativeShaper.connect(this.negativeOutputGain);\n this.negativeOutputGain.connect(this.outFilter);\n\n // ConstantSourceNode (Input as Fuzz) -> AudioParam (gain as negative output gain)\n this.driveInput.connect(this.negativeOutputGain.gain);\n\n // BiquadFilterNode (High-pass) -> GainNode (Fuzz Level) -> GainNode (Output)\n this.outFilter.connect(this.level);\n this.level.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.output;\n }\n\n /**\n * This method gets or sets parameters for fuzz effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FuzzParams|FuzzParams} params This argument is string if getter. Otherwise, setter.\n * @return {FuzzParams[keyof FuzzParams]|Fuzz} Return value is parameter for fuzz effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'drive'): number;\n public param(params: 'level'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: FuzzParams): Fuzz;\n public param(params: keyof FuzzParams | FuzzParams): FuzzParams[keyof FuzzParams] | Fuzz {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'drive': {\n return this.drive;\n }\n\n case 'level': {\n return this.level.gain.value;\n }\n\n case 'oversample': {\n return this.positiveShaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'drive': {\n if (typeof value === 'number') {\n this.drive = value;\n this.driveInput.offset.value = this.drive;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level.gain.value = value;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.positiveShaper.oversample = value;\n this.negativeShaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FuzzParams> {\n return {\n state : this.isActive,\n drive : this.drive,\n level : this.level.gain.value,\n oversample: this.positiveShaper.oversample\n };\n }\n}\n","import type { Position3D } from './Panner';\n\nimport { Effector } from './Effector';\n\nexport type ListenerParams = {\n x?: number,\n y?: number,\n z?: number,\n fx?: number,\n fy?: number,\n fz?: number,\n ux?: number,\n uy?: number,\n uz?: number\n};\n\n/**\n * Effector's subclass for Listener.\n */\nexport class Listener extends Effector {\n private listener: AudioListener;\n\n private positions: Position3D;\n private forwards: Position3D;\n private ups: Position3D;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n // 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 // Initialize parameters\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n\n // Firefox does not support parameters as `AudioParam`\n // this.listener.positionX.value = this.positions.x;\n // this.listener.positionY.value = this.positions.y;\n // this.listener.positionZ.value = this.positions.z;\n\n // this.listener.forwardX.value = this.forwards.x;\n // this.listener.forwardY.value = this.forwards.y;\n // this.listener.forwardZ.value = this.forwards.z;\n\n // this.listener.upX.value = this.ups.x;\n // this.listener.upY.value = this.ups.y;\n // this.listener.upZ.value = this.ups.z;\n }\n\n /** @override */\n public override connect(): GainNode {\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for audio listener.\n * This method is overloaded for type interface and type check.\n * @param {keyof ListenerParams|ListenerParams} params This argument is string if getter. Otherwise, setter.\n * @return {ListenerParams[keyof ListenerParams]|Listener} Return value is parameter for audio listener if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'x'): number;\n public param(params: 'y'): number;\n public param(params: 'z'): number;\n public param(params: 'fx'): number;\n public param(params: 'fy'): number;\n public param(params: 'fz'): number;\n public param(params: 'ux'): number;\n public param(params: 'uy'): number;\n public param(params: 'uz'): number;\n public param(params: ListenerParams): Listener;\n public param(params: keyof ListenerParams | ListenerParams): ListenerParams[keyof ListenerParams] | Listener {\n if (typeof params === 'string') {\n switch (params) {\n case 'x': {\n return this.positions.x;\n }\n\n case 'y': {\n return this.positions.y;\n }\n\n case 'z': {\n return this.positions.z;\n }\n\n case 'fx': {\n return this.forwards.x;\n }\n\n case 'fy': {\n return this.forwards.y;\n }\n\n case 'fz': {\n return this.forwards.z;\n }\n\n case 'ux': {\n return this.ups.x;\n }\n\n case 'uy': {\n return this.ups.y;\n }\n\n case 'uz': {\n return this.ups.z;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'x': {\n if (typeof value === 'number') {\n this.positions.x = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'y': {\n if (typeof value === 'number') {\n this.positions.y = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'z': {\n if (typeof value === 'number') {\n this.positions.z = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'fx': {\n if (typeof value === 'number') {\n this.forwards.x = value;\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 break;\n }\n\n case 'fy': {\n if (typeof value === 'number') {\n this.forwards.y = value;\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 break;\n }\n\n case 'fz': {\n if (typeof value === 'number') {\n this.forwards.z = value;\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 break;\n }\n\n case 'ux': {\n if (typeof value === 'number') {\n this.ups.x = value;\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 break;\n }\n\n case 'uy': {\n if (typeof value === 'number') {\n this.ups.y = value;\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 break;\n }\n\n case 'uz': {\n if (typeof value === 'number') {\n this.ups.z = value;\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 break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<ListenerParams> {\n return {\n x : this.positions.x,\n y : this.positions.y,\n z : this.positions.z,\n fx: this.forwards.x,\n fy: this.forwards.y,\n fz: this.forwards.z,\n ux: this.ups.x,\n uy: this.ups.y,\n uz: this.ups.z\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { NoiseGateParams } from '../NoiseGate';\n\nimport { AudioWorkletProcessor } from '../../../worklet';\n\ninterface NoiseGateProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n noisegate: (level: number) => number;\n alloc_memory_inputs: () => number;\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Override `process` method for noise gate and Update parameters on message event.\n */\nexport class NoiseGateProcessor extends AudioWorkletProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private level = 0;\n private isActive = true;\n\n constructor() {\n super();\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | NoiseGateParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if (!this.isActive || (this.level === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as NoiseGateProcessorWebAssemblyInstance;;\n\n const linearMemory = wasm.memory.buffer;\n\n const bufferSize = input[0].length;\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs();\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, bufferSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.noisegate(this.level);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { NoiseGateProcessor } from './AudioWorkletProcessors/NoiseGateProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/noisegate.wasm';\n\nexport type NoiseGateParams = {\n state?: boolean,\n level?: number\n};\n\n/**\n * This private class is for Noise Gate.\n */\nexport class NoiseGate extends Effector {\n private processor: AudioWorkletNode;\n\n private level = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, NoiseGateProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Noise Gate) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for noise gate.\n * @param {keyof NoiseGateParams|NoiseGateParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseGateParams[keyof NoiseGateParams]|NoiseGate} Return value is parameter for noise gate if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'level'): number;\n public param(params: NoiseGateParams): NoiseGate;\n public param(params: keyof NoiseGateParams | NoiseGateParams): NoiseGateParams[keyof NoiseGateParams] | NoiseGate {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'level': {\n return this.level;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: NoiseGateParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const message: NoiseGateParams = { level: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public params(): Required<NoiseGateParams> {\n return {\n state: this.isActive,\n level: this.level\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { NoiseSuppressorParams } from '../NoiseSuppressor';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface NoiseSuppressorProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n noisesuppressor: (threshold: number, fftSize: number) => number;\n alloc_memory_inputs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for noise suppressor and Update parameters on message event.\n */\nexport class NoiseSuppressorProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private threshold = 0;\n private isActive = true;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = async (event: MessageEvent<ArrayBuffer | NoiseSuppressorParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if (!this.isActive || (this.threshold === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as NoiseSuppressorProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs(this.frameSize);\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, this.frameSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.noisesuppressor(this.threshold, this.frameSize);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, this.frameSize));\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { NoiseSuppressorProcessor } from './AudioWorkletProcessors/NoiseSuppressorProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/noisesuppressor.wasm';\n\nexport type NoiseSuppressorParams = {\n state?: boolean,\n threshold?: number\n};\n\n/**\n * This private class is for Noise Suppressor.\n */\nexport class NoiseSuppressor extends Effector {\n private processor: AudioWorkletNode;\n\n private threshold = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, NoiseSuppressorProcessor.name, {\n processorOptions: {\n frameSize: 1024\n }\n });\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Noise Suppressor) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for noise suppressor.\n * @param {keyof NoiseSuppressorParams|NoiseSuppressorParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseSuppressorParams[keyof NoiseSuppressorParams]|NoiseSuppressor} Return value is parameter for noise suppressor if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'threshold'): number;\n public param(params: NoiseSuppressorParams): NoiseSuppressor;\n public param(params: keyof NoiseSuppressorParams | NoiseSuppressorParams): NoiseSuppressorParams[keyof NoiseSuppressorParams] | NoiseSuppressor {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'threshold': {\n return this.threshold;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: NoiseSuppressorParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n if (value >= 0) {\n this.threshold = value;\n\n const message: NoiseSuppressorParams = { threshold: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<NoiseSuppressorParams> {\n return {\n state : this.isActive,\n threshold: this.threshold\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type OverDriveParams = {\n state?: boolean,\n drive?: number,\n level?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for OverDrive.\n */\nexport class OverDrive extends Effector {\n private shaper: WaveShaperNode;\n private inputShaper: WaveShaperNode;\n private outputShaper: WaveShaperNode;\n private inputGain: GainNode;\n private outputGain: GainNode;\n private driveInput: ConstantSourceNode;\n private level: GainNode;\n\n private drive = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = this.context.createWaveShaper();\n this.inputShaper = this.context.createWaveShaper();\n this.outputShaper = this.context.createWaveShaper();\n\n this.inputGain = this.context.createGain();\n this.outputGain = this.context.createGain();\n\n this.driveInput = this.context.createConstantSource();\n\n this.level = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1024);\n\n for (let i = 0; i < 512; i++) {\n const r = Math.tanh((4 * i) / 512) * 0.5;\n\n curve[512 + i] = r;\n curve[511 - i] = -r;\n }\n\n const inputCurve = new Float32Array(101);\n\n for (let i = 0; i < 101; i++) {\n inputCurve[i] = 0.25;\n }\n\n for (let i = 52, d1 = 0.25; i < 101; i++, d1 *= 1.1) {\n inputCurve[i] = d1;\n }\n\n const outputCurve = new Float32Array([2, 2, 2, 2, 2, 0.9, 0.5, 0.35, 0.3]);\n\n this.shaper.curve = curve;\n this.shaper.oversample = '4x';\n this.inputShaper.curve = inputCurve;\n this.outputShaper.curve = outputCurve;\n\n this.inputGain.gain.value = 0;\n this.outputGain.gain.value = 0;\n\n this.driveInput.offset.value = this.drive;\n\n this.level.gain.value = 1;\n\n // `OverDrive` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.driveInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.driveInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.driveInput = this.context.createConstantSource();\n\n // Restore parameters\n this.driveInput.offset.value = this.drive;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.shaper.disconnect(0);\n this.inputShaper.disconnect(0);\n this.outputShaper.disconnect(0);\n this.inputGain.disconnect(0);\n this.outputGain.disconnect(0);\n this.driveInput.disconnect(0);\n this.level.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Input Gain) -> WaveShaperNode (OverDrive) -> GainNode (Output Gain) -> GainNode (OverDrive Level) -> GainNode (Output)\n this.input.connect(this.inputGain);\n this.inputGain.connect(this.shaper);\n this.shaper.connect(this.outputGain);\n this.outputGain.connect(this.level);\n this.level.connect(this.output);\n\n // ConstantSourceNode (Input as OverDrive) -> WaveShaperNode (Input Envelope Follower) -> AudioParam (gain as input)\n this.driveInput.connect(this.inputShaper);\n this.inputShaper.connect(this.inputGain.gain);\n\n // ConstantSourceNode (Input as OverDrive) -> WaveShaperNode (Output Envelope Follower) -> AudioParam (gain as output)\n this.driveInput.connect(this.outputShaper);\n this.outputShaper.connect(this.outputGain.gain);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for overdrive effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof OverDriveParams|OverDriveParams} params This argument is string if getter. Otherwise, setter.\n * @return {OverDriveParams[keyof OverDriveParams]|OverDrive} Return value is parameter for overdrive effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'drive'): number;\n public param(params: 'level'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: OverDriveParams): OverDrive;\n public param(params: keyof OverDriveParams | OverDriveParams): OverDriveParams[keyof OverDriveParams] | OverDrive {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'drive': {\n return this.drive;\n }\n\n case 'level': {\n return this.level.gain.value;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'drive': {\n if (typeof value === 'number') {\n this.drive = value;\n this.driveInput.offset.value = this.drive;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level.gain.value = value;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<OverDriveParams> {\n return {\n state : this.isActive,\n drive : this.drive,\n level : this.level.gain.value,\n oversample: this.shaper.oversample\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type Position3D = {\n x: number,\n y: number,\n z: number\n};\n\nexport type PannerParams = {\n state?: boolean,\n x?: number,\n y?: number,\n z?: number,\n ox?: number,\n oy?: number,\n oz?: number,\n refDistance?: number,\n maxDistance?: number,\n rolloffFactor?: number,\n coneInnerAngle?: number,\n coneOuterAngle?: number,\n coneOuterGain?: number,\n panningModel: PanningModelType,\n distanceModel: DistanceModelType\n};\n\n/**\n * Effector's subclass for Panner.\n */\nexport class Panner extends Effector {\n private panner: PannerNode;\n private positions: Position3D;\n private orientations: Position3D;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\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 = 'HRTF';\n this.panner.distanceModel = 'inverse';\n\n this.panner.positionX.value = this.positions.x;\n this.panner.positionY.value = this.positions.y;\n this.panner.positionZ.value = this.positions.z;\n\n this.panner.orientationX.value = this.orientations.x;\n this.panner.orientationY.value = this.orientations.y;\n this.panner.orientationZ.value = this.orientations.z;\n\n // `Panner` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Pan) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for panner.\n * This method is overloaded for type interface and type check.\n * @param {keyof PannerParams|PannerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PannerParams[keyof PannerParams]|PannerParams} Return value is parameter for panner if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'x'): number;\n public param(params: 'y'): number;\n public param(params: 'z'): number;\n public param(params: 'ox'): number;\n public param(params: 'oy'): number;\n public param(params: 'oz'): number;\n public param(params: 'refDistance'): number;\n public param(params: 'maxDistance'): number;\n public param(params: 'rolloffFactor'): number;\n public param(params: 'coneInnerAngle'): number;\n public param(params: 'coneOuterAngle'): number;\n public param(params: 'coneOuterGain'): number;\n public param(params: 'panningModel'): PanningModelType;\n public param(params: 'distanceModel'): DistanceModelType;\n public param(params: PannerParams): Panner;\n public param(params: keyof PannerParams | PannerParams): PannerParams[keyof PannerParams] | Panner {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'x': {\n return this.panner.positionX.value;\n }\n\n case 'y': {\n return this.panner.positionY.value;\n }\n\n case 'z': {\n return this.panner.positionZ.value;\n }\n\n case 'ox': {\n return this.panner.orientationX.value;\n }\n\n case 'oy': {\n return this.panner.orientationY.value;\n }\n\n case 'oz': {\n return this.panner.orientationZ.value;\n }\n\n case 'refDistance': {\n return this.panner.refDistance;\n }\n\n case 'maxDistance': {\n return this.panner.maxDistance;\n }\n\n case 'rolloffFactor': {\n return this.panner.rolloffFactor;\n }\n\n case 'coneInnerAngle': {\n return this.panner.coneInnerAngle;\n }\n\n case 'coneOuterAngle': {\n return this.panner.coneOuterAngle;\n }\n\n case 'coneOuterGain': {\n return this.panner.coneOuterGain;\n }\n\n case 'panningModel': {\n return this.panner.panningModel;\n }\n\n case 'distanceModel': {\n return this.panner.distanceModel;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'x': {\n if (typeof value === 'number') {\n this.panner.positionX.value = value;\n }\n\n break;\n }\n\n case 'y': {\n if (typeof value === 'number') {\n this.panner.positionY.value = value;\n }\n\n break;\n }\n\n case 'z': {\n if (typeof value === 'number') {\n this.panner.positionZ.value = value;\n }\n\n break;\n }\n\n case 'ox': {\n if (typeof value === 'number') {\n this.panner.orientationX.value = value;\n }\n\n break;\n }\n\n case 'oy': {\n if (typeof value === 'number') {\n this.panner.orientationY.value = value;\n }\n\n break;\n }\n\n case 'oz': {\n if (typeof value === 'number') {\n this.panner.orientationZ.value = value;\n }\n\n break;\n }\n\n case 'refDistance': {\n if (typeof value === 'number') {\n this.panner.refDistance = value;\n }\n\n break;\n }\n\n case 'maxDistance': {\n if (typeof value === 'number') {\n this.panner.maxDistance = value;\n }\n\n break;\n }\n\n case 'rolloffFactor': {\n if (typeof value === 'number') {\n this.panner.rolloffFactor = value;\n }\n\n break;\n }\n\n case 'coneInnerAngle': {\n if (typeof value === 'number') {\n this.panner.coneInnerAngle = value;\n }\n\n break;\n }\n\n case 'coneOuterAngle': {\n if (typeof value === 'number') {\n this.panner.coneOuterAngle = value;\n }\n\n break;\n }\n\n case 'coneOuterGain': {\n if (typeof value === 'number') {\n this.panner.coneOuterGain = value;\n }\n\n break;\n }\n\n case 'panningModel': {\n if ((value === 'HRTF') || (value === 'equalpower')) {\n this.panner.panningModel = value;\n }\n\n break;\n }\n\n case 'distanceModel': {\n if ((value === 'linear') || (value === 'inverse') || (value === 'exponential')) {\n this.panner.distanceModel = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PannerParams> {\n return {\n state : this.isActive,\n x : this.positions.x,\n y : this.positions.y,\n z : this.positions.z,\n ox : this.orientations.x,\n oy : this.orientations.y,\n oz : this.orientations.z,\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}\n","import { Effector } from './Effector';\n\nexport type PhaserNumberOfStages = 0 | 2 | 4 | 8 | 12 | 24;\n\nexport type PhaserParams = {\n state?: boolean,\n stage?: PhaserNumberOfStages,\n frequency?: number,\n resonance?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number\n};\n\n/**\n * Effector's subclass for Phaser.\n */\nexport class Phaser extends Effector {\n public static MAX_STAGES = 24; // The max number of All-pass Filters\n\n private numberOfStages: PhaserNumberOfStages = 12; // The default number of All-pass Filters\n private filters: BiquadFilterNode[] = [];\n private dry: GainNode;\n private wet: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n const filter = context.createBiquadFilter();\n\n filter.type = 'allpass';\n filter.frequency.value = 350;\n filter.Q.value = 1;\n filter.gain.value = 0; // Not used\n\n this.filters.push(filter);\n }\n\n this.dry = context.createGain();\n this.wet = context.createGain();\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n\n // `Phaser` is not connected by default\n this.deactivate();\n\n // LFO\n // GainNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n /** @override */\n public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.filters[i].disconnect(0);\n }\n\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n\n if (this.isActive && (this.numberOfStages > 0)) {\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 (All-pass Filter x N) -> GainNode (Wet) -> 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.wet);\n this.wet.connect(this.output);\n }\n }\n\n // Phaser don't work in Firefox if there is feedback connection.\n // GainNode (Input) -> BiquadFilterNode (All-pass Filter x N) -> GainNode (Feedback) -> BiquadFilterNode (All-pass Filter x N) ...\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for phaser effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof PhaserParams|PhaserParams} params This argument is string if getter. Otherwise, setter.\n * @return {PhaserParams[keyof PhaserParams]|Phaser} Return value is parameter for phaser effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'stage'): PhaserNumberOfStages;\n public param(params: 'frequency'): number;\n public param(params: 'resonance'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: PhaserParams): Phaser;\n public param(params: keyof PhaserParams | PhaserParams): PhaserParams[keyof PhaserParams] | Phaser {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'stage': {\n return this.numberOfStages;\n }\n\n case 'frequency': {\n return this.filters[0].frequency.value;\n }\n\n case 'resonance': {\n return this.filters[0].Q.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'stage': {\n switch (value) {\n case 0:\n case 2:\n case 4:\n case 8:\n case 12:\n case 24: {\n this.numberOfStages = value;\n\n // Update connection\n this.connect();\n break;\n }\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n for (const filter of this.filters) {\n filter.frequency.value = value;\n }\n\n this.depth.gain.value = value * this.depthRate;\n }\n\n break;\n }\n\n case 'resonance': {\n if (typeof value === 'number') {\n for (const filter of this.filters) {\n filter.Q.value = value;\n }\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.filters[0].frequency.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PhaserParams> {\n return {\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.wet.gain.value,\n dry : this.dry.gain.value,\n wet : this.wet.gain.value\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { PitchShifterParams } from '../PitchShifter';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface PitchShifterProcessorebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n pitchshifter: (pitch: number, speed: number, fftSize: number, timeCursor: number) => number;\n alloc_memory_inputs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for pitch shifter and Update parameters on message event.\n */\nexport class PitchShifterProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private timeCursor = 0;\n\n private isActive = true;\n private pitch = 1;\n private speed = 1;\n\n private dry = 0;\n private wet = 1;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = async (event: MessageEvent<ArrayBuffer | PitchShifterParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'pitch': {\n if (typeof value === 'number') {\n this.pitch = value;\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n this.speed = value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): void {\n if (this.instance === null) {\n return;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if (!this.isActive || ((this.pitch === 1) && (this.speed === 1))) {\n for (let channelNumber = 0; channelNumber < input.length; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return;\n }\n\n // HACK:\n const wasm = this.instance.exports as PitchShifterProcessorebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0; channelNumber < input.length; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs(this.frameSize);\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, this.frameSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.pitchshifter(this.pitch, this.speed, this.frameSize, this.timeCursor);\n\n const shiftedOutput = new Float32Array(linearMemory, offsetOutput, this.frameSize);\n\n if (this.dry === 0) {\n output[channelNumber].set(shiftedOutput);\n } else {\n for (let n = 0; n < this.frameSize; n++) {\n output[channelNumber][n] = (this.dry * input[channelNumber][n]) + (this.wet * shiftedOutput[n]);\n }\n }\n }\n\n this.timeCursor += this.hopSize;\n }\n}\n","import { Effector } from './Effector';\nimport { PitchShifterProcessor } from './AudioWorkletProcessors/PitchShifterProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/pitchshifter.wasm';\n\nexport type PitchShifterParams = {\n state?: boolean,\n pitch?: number,\n speed?: number,\n dry?: number,\n wet?: number\n};\n\n/**\n * Effector's subclass for Pitch Shifter.\n */\nexport class PitchShifter extends Effector {\n private processor: AudioWorkletNode;\n\n private pitch = 1;\n private speed = 1;\n\n private dry = 0;\n private wet = 1;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, PitchShifterProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Pitch Shifter) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for pitch shifter.\n * This method is overloaded for type interface and type check.\n * @param {keyof PitchShifterParams|PitchShifterParams} params This argument is string if getter. Otherwise, setter.\n * @return {PitchShifterParams[keyof PitchShifterParams]|PitchShifter} Return value is parameter for pitch shifter if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pitch'): number;\n public param(params: 'speed'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: PitchShifterParams): PitchShifter;\n public param(params: keyof PitchShifterParams | PitchShifterParams): PitchShifterParams[keyof PitchShifterParams] | PitchShifter {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pitch': {\n return this.pitch;\n }\n\n case 'speed': {\n return this.speed;\n }\n\n case 'dry': {\n return this.dry;\n }\n\n case 'wet': {\n return this.wet;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: PitchShifterParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'pitch': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.pitch = value;\n\n const message: PitchShifterParams = { pitch: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.speed = value;\n\n const message: PitchShifterParams = { speed: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value <= 1)) {\n this.dry = value;\n\n const message: PitchShifterParams = { dry: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value <= 1)) {\n this.wet = value;\n\n const message: PitchShifterParams = { wet: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PitchShifterParams> {\n return {\n state: this.isActive,\n pitch: this.pitch,\n speed: this.speed,\n dry : this.dry,\n wet : this.wet\n };\n }\n}\n","import { Effector } from '../Effector';\n\nexport type CabinetParams = {\n state?: boolean\n};\n\n/**\n * Effector's subclass for Cabinet.\n */\nexport class Cabinet extends Effector {\n private lowpass: BiquadFilterNode;\n private notch: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.lowpass = context.createBiquadFilter();\n this.notch = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 3200;\n this.lowpass.Q.value = 6;\n this.lowpass.gain.value = 0; // Not used\n\n this.notch.type = 'notch';\n this.notch.frequency.value = 8000;\n this.notch.Q.value = 1;\n this.notch.gain.value = 0; // Not used\n\n // `Cabinet` is connected by default\n this.activate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Notch) -> BiquadFilterNode (Low-pass) -> GainNode (Output)\n this.input.connect(this.notch);\n this.notch.connect(this.lowpass);\n this.lowpass.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.output;\n }\n\n /**\n * This method gets or sets parameters for cabinet.\n * This method is overloaded for type interface and type check.\n * @param {keyof CabinetParams|CabinetParams} params This argument is string if getter. Otherwise, setter.\n * @return {CabinetParams[keyof CabinetParams]} Return value is parameter for cabinet if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: CabinetParams): void;\n public param(params: keyof CabinetParams | CabinetParams): CabinetParams[keyof CabinetParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<CabinetParams> {\n return {\n state: this.isActive\n };\n }\n}\n","import type { PreampCurve } from '../Preamp';\nimport type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type PreEqualizerParams = {\n state?: boolean,\n curve?: PreampCurve,\n oversample?: OverSampleType,\n gain?: number,\n lead?: number\n};\n\nexport type PostEqualizerParams = {\n state?: boolean,\n curve?: PreampCurve,\n oversample?: OverSampleType,\n bass?: number,\n middle?: number,\n treble?: number,\n frequency?: number\n};\n\nexport type MarshallParams = {\n state?: boolean,\n level?: number,\n samples?: number,\n pre?: PreEqualizerParams,\n post?: PostEqualizerParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private shaper: WaveShaperNode;\n private preGain: GainNode;\n private leadGain: GainNode;\n private lowpass: BiquadFilterNode;\n private highpass1: BiquadFilterNode;\n private highpass2: BiquadFilterNode;\n private highpass3: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = context.createWaveShaper();\n\n this.preGain = context.createGain();\n this.leadGain = context.createGain();\n\n this.lowpass = context.createBiquadFilter();\n this.highpass1 = context.createBiquadFilter();\n this.highpass2 = context.createBiquadFilter();\n this.highpass3 = context.createBiquadFilter();\n\n // Initialize parameters\n this.shaper.oversample = '4x';\n\n this.preGain.gain.value = 0.5;\n this.leadGain.gain.value = 0.5;\n\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 3200;\n this.lowpass.Q.value = -3;\n this.lowpass.gain.value = 0; // Not used\n\n this.highpass1.type = 'highpass';\n this.highpass1.frequency.value = 80;\n this.highpass1.Q.value = -3;\n this.highpass1.gain.value = 0; // Not used\n\n this.highpass2.type = 'highpass';\n this.highpass2.frequency.value = 640;\n this.highpass2.Q.value = -3;\n this.highpass2.gain.value = 0; // Not used\n\n this.highpass3.type = 'highpass';\n this.highpass3.frequency.value = 80;\n this.highpass3.Q.value = -3;\n this.highpass3.gain.value = 0; // Not used\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Low-pass) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.highpass1);\n this.highpass1.connect(this.lowpass);\n this.lowpass.connect(this.preGain);\n this.preGain.connect(this.highpass3);\n\n // GainNode (Input) -> BiquadFilterNode (High-pass) -> GainNode (Lead-gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.highpass2);\n this.highpass2.connect(this.leadGain);\n this.leadGain.connect(this.highpass3);\n\n // BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping) -> GainNode (Output)\n this.highpass3.connect(this.shaper);\n this.shaper.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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'curve'): PreampCurve;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'gain'): number;\n public param(params: 'lead'): number;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'curve': {\n return this.shaper.curve;\n }\n\n case 'oversample': {\n return this.shaper.curve;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'lead': {\n return this.leadGain.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'curve': {\n if ((typeof value !== 'number') && (typeof value !== 'boolean')) {\n if ((value instanceof Float32Array) || (value === null)) {\n this.shaper.curve = value;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'lead': {\n if (typeof value === 'number') {\n this.leadGain.gain.value = value;\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n curve : this.shaper.curve,\n gain : this.preGain.gain.value,\n lead : this.leadGain.gain.value,\n oversample: this.shaper.oversample\n };\n }\n}\n\n/**\n * Effector's subclass for Post-Equalizer.\n */\nclass PostEqualizer extends Effector {\n private shaper: WaveShaperNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private lowpass: BiquadFilterNode;\n private highpass: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = context.createWaveShaper();\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.shaper.oversample = '4x';\n\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 240; // 240 Hz\n this.middle.frequency.value = 500; // 500 Hz\n this.treble.frequency.value = 1600; // 1.6 kHz\n\n // Set Q\n this.bass.Q.value = 0; // Not used\n this.middle.Q.value = 1.5;\n this.treble.Q.value = 0; // 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\n this.lowpass = context.createBiquadFilter();\n this.highpass = context.createBiquadFilter();\n\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 4000;\n this.lowpass.Q.value = -3;\n this.lowpass.gain.value = 0; // Not used\n\n this.highpass.type = 'highpass';\n this.highpass.frequency.value = 40;\n this.highpass.Q.value = -3;\n this.highpass.gain.value = 0; // Not used\n\n // `PostEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Low-pass) -> BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving) -> GainNode (Output)\n this.input.connect(this.lowpass);\n this.lowpass.connect(this.highpass);\n this.highpass.connect(this.shaper);\n this.shaper.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.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.output;\n }\n\n /**\n * This method gets or sets parameters for post-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostEqualizerParams|PostEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostEqualizerParams[keyof PostEqualizerParams]} Return value is parameter for post-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'curve'): PreampCurve;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'frequency'): number;\n public param(params: PostEqualizerParams): void;\n public param(params: keyof PostEqualizerParams | PostEqualizerParams): PostEqualizerParams[keyof PostEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'curve': {\n return this.shaper.curve;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'frequency': {\n return this.middle.frequency.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'curve': {\n if ((typeof value !== 'number') && (typeof value !== 'boolean')) {\n if ((value instanceof Float32Array) || (value === null)) {\n this.shaper.curve = value;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n this.middle.frequency.value = value;\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PostEqualizerParams> {\n return {\n state : this.isActive,\n curve : this.shaper.curve,\n oversample: this.shaper.oversample,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n frequency : this.middle.frequency.value\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (Marshall).\n */\nexport class Marshall extends Effector {\n private preEQ: PreEqualizer;\n private postEQ: PostEqualizer;\n private cabinet: Cabinet;\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postEQ = new PostEqualizer(context);\n this.cabinet = new Cabinet(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Post-Equalizer -> Cabinet -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.postEQ.INPUT);\n this.postEQ.OUTPUT.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof MarshallParams|MarshallParams} params This argument is string if getter. Otherwise, setter.\n * @return {MarshallParams[keyof MarshallParams]|Marshall} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'pre'): MarshallParams['pre'];\n public param(params: 'post'): MarshallParams['post'];\n public param(params: 'cabinet'): CabinetParams;\n public param(params: MarshallParams): Marshall;\n public param(params: keyof MarshallParams | MarshallParams): MarshallParams[keyof MarshallParams] | Marshall {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postEQ.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postEQ.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postEQ.deactivate();\n }\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n this.preEQ.param({ curve });\n this.postEQ.param({ curve });\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n this.preEQ.param({ curve });\n this.postEQ.param({ curve });\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postEQ.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<MarshallParams> {\n return {\n state : this.isActive,\n level : this.level,\n samples: this.numberOfSamples,\n pre : this.preEQ.params(),\n post : this.postEQ.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type PreEqualizerParams = {\n state?: boolean,\n gain?: number,\n bass?: number,\n middle?: number,\n treble?: number,\n level?: number,\n samples?: number,\n oversample?: OverSampleType,\n postFilters?: boolean\n};\n\nexport type PostEqualizerParams = {\n state?: boolean,\n fc100?: number,\n fc360?: number,\n fc720?: number,\n fc1600?: number,\n fc4800?: number\n};\n\nexport type MesaBoogieParams = {\n state?: boolean,\n pre?: PreEqualizerParams,\n post?: PostEqualizerParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private preGain: GainNode;\n\n private preHighpass: BiquadFilterNode;\n private postHighpass: BiquadFilterNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private shapers: WaveShaperNode[] = [];\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n // Optional filters\n private usePostFilters = true;\n private lowpass: BiquadFilterNode;\n private highpass: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preGain = context.createGain();\n\n // Initialize parameters\n this.preGain.gain.value = 0.5;\n\n this.preHighpass = context.createBiquadFilter();\n this.postHighpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.preHighpass.type = 'highpass';\n this.postHighpass.type = 'highpass';\n\n this.preHighpass.frequency.value = 40; // 40 Hz\n this.postHighpass.frequency.value = 80; // 80 Hz\n\n this.preHighpass.Q.value = -3;\n this.postHighpass.Q.value = -3;\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 160; // 160 Hz\n this.middle.frequency.value = 284; // 284 Hz\n this.treble.frequency.value = 1200; // 1.2 kHz\n\n // Set Q\n this.middle.Q.value = 1.5;\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n // Initialize parameters\n for (let i = 0; i < 2; i++) {\n this.shapers[i] = context.createWaveShaper();\n\n this.shapers[i].curve = curve;\n this.shapers[i].oversample = '4x';\n }\n\n this.lowpass = context.createBiquadFilter();\n this.highpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.highpass.type = 'highpass';\n\n this.lowpass.frequency.value = 4000; // 4 kHz\n this.highpass.frequency.value = 40; // 40 Hz\n\n this.lowpass.Q.value = -3;\n this.highpass.Q.value = -3;\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving) -> WaveShaperNode (Clipping) -> BiquadFilterNode (Low-pass)\n this.input.connect(this.preGain);\n this.preGain.connect(this.preHighpass);\n this.preHighpass.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.connect(this.postHighpass);\n this.postHighpass.connect(this.shapers[0]);\n\n if (this.usePostFilters) {\n // WaveShaperNode (Clipping) -> BiquadFilterNode (Low-pass) -> BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping)\n this.shapers[0].connect(this.lowpass);\n this.lowpass.connect(this.highpass);\n this.highpass.connect(this.shapers[1]);\n } else {\n // WaveShaperNode (Clipping) -> WaveShaperNode (Clipping)\n this.shapers[0].connect(this.shapers[1]);\n }\n\n // WaveShaperNode (Clipping) -> GainNode (Output);\n this.shapers[1].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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'gain'): number;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'postFilters'): boolean;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'oversample': {\n return this.shapers[0].oversample;\n }\n\n case 'postFilters': {\n return this.usePostFilters;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 2; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 2; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n for (let i = 0; i < 2; i++) {\n this.shapers[i].oversample = value;\n }\n }\n }\n\n break;\n }\n\n case 'postFilters': {\n if (typeof value === 'boolean') {\n this.usePostFilters = value;\n this.connect();\n }\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n gain : this.preGain.gain.value,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n level : this.level,\n samples : this.numberOfSamples,\n oversample : this.shapers[0].oversample,\n postFilters: this.usePostFilters\n };\n }\n}\n\n/**\n * Effector's subclass for Post-Equalizer.\n */\nclass PostEqualizer extends Effector {\n private peakingFilters: BiquadFilterNode[] = [];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n for (let i = 0; i < 5; i++) {\n this.peakingFilters[i] = context.createBiquadFilter();\n\n // Initialize parameters\n this.peakingFilters[i].type = 'peaking';\n this.peakingFilters[i].gain.value = 0;\n }\n\n // Set cutoff frequency\n this.peakingFilters[0].frequency.value = 100; // 100 Hz\n this.peakingFilters[1].frequency.value = 360; // 360 Hz\n this.peakingFilters[2].frequency.value = 720; // 720 Hz\n this.peakingFilters[3].frequency.value = 1600; // 1.6 kHz\n this.peakingFilters[4].frequency.value = 4800; // 4.8 kHz\n\n // Set Q\n this.peakingFilters[0].Q.value = 1.5;\n this.peakingFilters[1].Q.value = 2.0;\n this.peakingFilters[2].Q.value = 2.0;\n this.peakingFilters[3].Q.value = 1.1;\n this.peakingFilters[4].Q.value = 1.2;\n\n // `PostEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n this.input.connect(this.peakingFilters[0]);\n\n for (let i = 0, len = (this.peakingFilters.length - 1); i < len; i++) {\n this.peakingFilters[i].connect(this.peakingFilters[i + 1]);\n }\n\n this.peakingFilters[4].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.output;\n }\n\n /**\n * This method gets or sets parameters for post-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostEqualizerParams|PostEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostEqualizerParams[keyof PostEqualizerParams]} Return value is parameter for post-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'fc100'): number;\n public param(params: 'fc360'): number;\n public param(params: 'fc720'): number;\n public param(params: 'fc1600'): number;\n public param(params: 'fc4800'): number;\n public param(params: PostEqualizerParams): void;\n public param(params: keyof PostEqualizerParams | PostEqualizerParams): PostEqualizerParams[keyof PostEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'fc100': {\n return this.peakingFilters[0].gain.value;\n }\n\n case 'fc360': {\n return this.peakingFilters[1].gain.value;\n }\n\n case 'fc720': {\n return this.peakingFilters[2].gain.value;\n }\n\n case 'fc1600': {\n return this.peakingFilters[3].gain.value;\n }\n\n case 'fc4800': {\n return this.peakingFilters[4].gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'fc100': {\n if (typeof value === 'number') {\n this.peakingFilters[0].gain.value = value;\n }\n\n break;\n }\n\n case 'fc360': {\n if (typeof value === 'number') {\n this.peakingFilters[1].gain.value = value;\n }\n\n break;\n }\n\n case 'fc720': {\n if (typeof value === 'number') {\n this.peakingFilters[2].gain.value = value;\n }\n\n break;\n }\n\n case 'fc1600': {\n if (typeof value === 'number') {\n this.peakingFilters[3].gain.value = value;\n }\n\n break;\n }\n\n case 'fc4800': {\n if (typeof value === 'number') {\n this.peakingFilters[4].gain.value = value;\n }\n\n break;\n }\n }\n }\n }\n /** @override */\n public override params(): Required<PostEqualizerParams> {\n return {\n state : this.isActive,\n fc100 : this.peakingFilters[0].gain.value,\n fc360 : this.peakingFilters[1].gain.value,\n fc720 : this.peakingFilters[2].gain.value,\n fc1600: this.peakingFilters[3].gain.value,\n fc4800: this.peakingFilters[4].gain.value,\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (MesaBoogie).\n */\nexport class MesaBoogie extends Effector {\n private preEQ: PreEqualizer;\n private postEQ: PostEqualizer;\n private cabinet: Cabinet;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postEQ = new PostEqualizer(context);\n this.cabinet = new Cabinet(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Cabinet -> Post-Equalizer -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.connect(this.postEQ.INPUT);\n this.postEQ.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof MesaBoogieParams|MesaBoogieParams} params This argument is string if getter. Otherwise, setter.\n * @return {MesaBoogieParams[keyof MesaBoogieParams]|MesaBoogie} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pre'): MesaBoogieParams['pre'];\n public param(params: 'post'): MesaBoogieParams['post'];\n public param(params: 'cabinet'): CabinetParams;\n public param(params: MesaBoogieParams): MesaBoogie;\n public param(params: keyof MesaBoogieParams | MesaBoogieParams): MesaBoogieParams[keyof MesaBoogieParams] | MesaBoogie {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postEQ.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postEQ.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postEQ.deactivate();\n }\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postEQ.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<MesaBoogieParams> {\n return {\n state : this.isActive,\n pre : this.preEQ.params(),\n post : this.postEQ.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type SpeakerInches = -1 | 10 | 12 | 15;\n\nexport type PreEqualizerParams = {\n state?: boolean,\n gain?: number,\n bass?: number,\n middle?: number,\n treble?: number,\n level?: number,\n samples?: number,\n oversample?: OverSampleType\n};\n\nexport type PostFilterParams = {\n state?: boolean,\n inch?: SpeakerInches,\n tilt?: boolean\n};\n\nexport type FenderParams = {\n state?: boolean,\n pre?: PreEqualizerParams,\n post?: PostFilterParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private preGain: GainNode;\n\n private highpass: BiquadFilterNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private gainEdge: GainNode;\n private gainBody: GainNode;\n private gainBottom: GainNode;\n\n private shapers: WaveShaperNode[] = [];\n private iirLowpassFilters: IIRFilterNode[] = [];\n private iirHighpassFilters: IIRFilterNode[] = [];\n\n private mixer: GainNode;\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preGain = context.createGain();\n\n // Initialize parameters\n this.preGain.gain.value = 0.5;\n\n this.highpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.highpass.type = 'highpass';\n this.highpass.frequency.value = 40; // 40 Hz\n this.highpass.Q.value = 1;\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 160; // 160 Hz\n this.middle.frequency.value = 284; // 284 Hz\n this.treble.frequency.value = 1200; // 1.2 kHz\n\n // Set Q\n this.middle.Q.value = 1.5;\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n\n this.gainEdge = context.createGain();\n this.gainBody = context.createGain();\n this.gainBottom = context.createGain();\n\n // Initialize parameters\n this.gainEdge.gain.value = 1;\n this.gainBody.gain.value = 1;\n this.gainBottom.gain.value = 1;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n // Initialize parameters\n for (let i = 0; i < 3; i++) {\n this.shapers[i] = context.createWaveShaper();\n\n this.shapers[i].curve = curve;\n this.shapers[i].oversample = '4x';\n }\n\n const coefficient1 = (220 / context.sampleRate) * Math.PI;\n const coefficient2 = (220 / context.sampleRate) * Math.PI;\n\n const lowpassFeedforward1 = new Float32Array([coefficient1, coefficient1]);\n const lowpassFeedforward2 = new Float32Array([coefficient2, coefficient2]);\n const lowpassFeedback1 = new Float32Array([1.0 + coefficient1, -1.0 + coefficient1]);\n const lowpassFeedback2 = new Float32Array([1.0 + coefficient2, -1.0 + coefficient2]);\n\n const highpassFeedforward1 = new Float32Array([1.0, -1.0]);\n const highpassFeedforward2 = new Float32Array([1.0, -1.0]);\n const highpassFeedback1 = new Float32Array([1.0 + coefficient1, -1.0 + coefficient1]);\n const highpassFeedback2 = new Float32Array([1.0 + coefficient2, -1.0 + coefficient2]);\n\n this.iirLowpassFilters[0] = context.createIIRFilter(lowpassFeedforward1, lowpassFeedback1);\n this.iirLowpassFilters[1] = context.createIIRFilter(lowpassFeedforward2, lowpassFeedback2);\n\n this.iirHighpassFilters[0] = context.createIIRFilter(highpassFeedforward1, highpassFeedback1);\n this.iirHighpassFilters[1] = context.createIIRFilter(highpassFeedforward2, highpassFeedback2);\n\n this.mixer = context.createGain();\n\n // Initialize parameters\n this.mixer.gain.value = 1;\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving)\n this.input.connect(this.preGain);\n this.preGain.connect(this.highpass);\n this.highpass.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n\n // Edge distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (High-pass) -> WaveShaperNode (Clipping) -> GainNode (Edge volume) -> GainNode (Mixer)\n this.treble.connect(this.iirHighpassFilters[1]);\n this.iirHighpassFilters[1].connect(this.shapers[0]);\n this.shapers[0].connect(this.gainEdge);\n this.gainEdge.connect(this.mixer);\n\n // Middle distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (High-pass) -> WaveShaperNode (Clipping) -> IIRFilterNode (Low-pass) -> GainNode (Body volume) -> GainNode (Mixer)\n this.treble.connect(this.iirHighpassFilters[0]);\n this.iirHighpassFilters[0].connect(this.shapers[1]);\n this.shapers[1].connect(this.iirLowpassFilters[1]);\n this.iirLowpassFilters[1].connect(this.gainBody);\n this.gainBody.connect(this.mixer);\n\n // Low distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (Low-pass) -> WaveShaperNode (Clipping) -> GainNode (Bottom volume) -> GainNode (Mixer)\n this.treble.connect(this.iirLowpassFilters[0]);\n this.iirLowpassFilters[0].connect(this.shapers[2]);\n this.shapers[2].connect(this.gainBottom);\n this.gainBottom.connect(this.mixer);\n\n\n // GainNode (Mixer) -> GainNode (Output)\n this.mixer.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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'gain'): number;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'oversample': {\n return this.shapers[0].oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 3; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 3; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n for (let i = 0; i < 3; i++) {\n this.shapers[i].oversample = value;\n }\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n gain : this.preGain.gain.value,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n level : this.level,\n samples : this.numberOfSamples,\n oversample: this.shapers[0].oversample\n };\n }\n}\n\n/**\n * Effector's subclass for Post-filter.\n */\nclass PostFilter extends Effector {\n private cabinet: Cabinet;\n\n private inch: SpeakerInches = -1;\n private tilt = false;\n\n private speakerFilter: BiquadFilterNode;\n private tiltFilter: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n * @param {Cabinet} cabinet This argument is instance of `Cabinet`.\n */\n constructor(context: AudioContext, cabinet: Cabinet) {\n super(context);\n\n this.cabinet = cabinet;\n\n this.speakerFilter = context.createBiquadFilter();\n\n // Initialize parameters\n this.speakerFilter.type = 'peaking';\n this.speakerFilter.frequency.value = 40; // 40 Hz\n this.speakerFilter.Q.value = -3;\n this.speakerFilter.gain.value = 0;\n\n this.tiltFilter = context.createBiquadFilter();\n\n // Initialize parameters\n this.tiltFilter.type = 'highshelf';\n this.tiltFilter.frequency.value = 3200; // 3.2 kHz\n this.tiltFilter.Q.value = Math.SQRT1_2;\n this.tiltFilter.gain.value = 0;\n\n // `PostFilter` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Cabinet -> BiquadFilterNode (Speaker inch) -> BiquadFilterNode (Speaker tilt) -> GainNode (Output)\n this.input.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.connect(this.speakerFilter);\n this.speakerFilter.connect(this.tiltFilter);\n this.tiltFilter.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.output;\n }\n\n /**\n * This method gets or sets parameters for post-filter.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostFilterParams|PostFilterParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostFilterParams[keyof PostFilterParams]} Return value is parameter for post-filter if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'inch'): SpeakerInches;\n public param(params: 'tilt'): boolean;\n public param(params: PostFilterParams): void;\n public param(params: keyof PostFilterParams | PostFilterParams): PostFilterParams[keyof PostFilterParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'inch': {\n return this.inch;\n }\n\n case 'tilt': {\n return this.tilt;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'inch': {\n if (typeof value === 'number') {\n switch (value) {\n case -1: {\n this.inch = -1;\n\n this.speakerFilter.frequency.value = 40;\n this.speakerFilter.Q.value = Math.SQRT1_2;\n this.speakerFilter.gain.value = 0;\n\n break;\n }\n\n case 10: {\n this.inch = 10;\n\n this.speakerFilter.frequency.value = 120;\n this.speakerFilter.Q.value = 3;\n this.speakerFilter.gain.value = 9;\n\n break;\n }\n\n case 12: {\n this.inch = 12;\n\n this.speakerFilter.frequency.value = 80;\n this.speakerFilter.Q.value = 6;\n this.speakerFilter.gain.value = 10;\n\n break;\n }\n\n case 15: {\n this.inch = 15;\n\n this.speakerFilter.frequency.value = 60;\n this.speakerFilter.Q.value = 9;\n this.speakerFilter.gain.value = 12;\n\n break;\n }\n }\n }\n\n break;\n }\n\n case 'tilt': {\n if (typeof value === 'boolean') {\n this.tilt = value;\n\n if (this.tilt) {\n this.tiltFilter.gain.value = 6;\n } else {\n this.tiltFilter.gain.value = 0;\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PostFilterParams> {\n return {\n state: this.isActive,\n inch : this.inch,\n tilt : this.tilt\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (Fender).\n */\nexport class Fender extends Effector {\n private preEQ: PreEqualizer;\n private postFilter: PostFilter;\n private cabinet: Cabinet;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.cabinet = new Cabinet(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postFilter = new PostFilter(context, this.cabinet);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Post-Filter (-> Cabinet) -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.postFilter.INPUT);\n this.postFilter.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FenderParams|FenderParams} params This argument is string if getter. Otherwise, setter.\n * @return {FenderParams[keyof FenderParams]|Fender} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pre'): FenderParams['pre']\n public param(params: 'post'): FenderParams['post']\n public param(params: 'cabinet'): CabinetParams;\n public param(params: FenderParams): Fender;\n public param(params: keyof FenderParams | FenderParams): FenderParams[keyof FenderParams] | Fender {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postFilter.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postFilter.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postFilter.deactivate();\n }\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postFilter.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FenderParams> {\n return {\n state : this.isActive,\n pre : this.preEQ.params(),\n post : this.postFilter.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { MarshallParams } from './Preamps/Marshall';\nimport type { MesaBoogieParams } from './Preamps/MesaBoogie';\nimport type { FenderParams } from './Preamps/Fender';\n\nimport { Effector } from './Effector';\nimport { Marshall } from './Preamps/Marshall';\nimport { MesaBoogie } from './Preamps/MesaBoogie';\nimport { Fender } from './Preamps/Fender';\n\nexport type PreampType = 'marshall' | 'mesa/boogie' | 'fender';\n\nexport type PreampCurve = Float32Array<ArrayBuffer> | null;\n\nexport type PreampParams = {\n state?: boolean,\n type?: PreampType,\n preamp?: MarshallParams | MesaBoogieParams | FenderParams\n};\n\n/**\n * This function creates instance of `Float32Array` for `WaveShaperNode`.\n * @param {number} level This argument is preamp effect level.\n * @param {number} numberOfSamples This argument is curve size.\n * @return {Float32Array|null} Return value is `WaveShaperNode`'s 'curve'.\n */\nexport function createCurve(level: number, numberOfSamples: number): PreampCurve {\n const index = Math.trunc((numberOfSamples - 1) / 2);\n\n const curves = new Float32Array(numberOfSamples);\n\n const d = (10 ** ((level / 5.0) - 1.0)) - 0.1;\n const c = (d / 5.0) + 1.0;\n\n let peak = 0.4;\n\n if (c === 1) {\n peak = 1.0;\n } else if ((c > 1) && (c < 1.04)) {\n peak = (-15.5 * c) + 16.52;\n }\n\n for (let i = 0; i < index; i++) {\n curves[index + i] = peak * (+1 - (c ** -i) + (i * (c ** -index)) / index);\n curves[index - i] = peak * (-1 + (c ** -i) - (i * (c ** -index)) / index);\n }\n\n curves[index] = 0;\n\n return curves;\n}\n\n/**\n * Effector's subclass for Preamplifier.\n */\nexport class Preamp extends Effector {\n private type: PreampType = 'marshall';\n private preamp: Marshall | MesaBoogie | Fender;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preamp = new Marshall(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // Create preamp connections\n this.preamp.connect();\n\n // GainNode (INPUT) -> Preamplifier -> GainNode (Output)\n this.input.connect(this.preamp.INPUT);\n this.preamp.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreampParams|PreampParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreampParams[keyof PreampParams]|Marshall|MesaBoogie|Fender} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): PreampType;\n public param(params: 'preamp'): PreampParams['preamp'];\n public param(params: PreampParams): Marshall | MesaBoogie | Fender;\n public param(params: keyof PreampParams | PreampParams): PreampParams[keyof PreampParams] | Marshall | MesaBoogie | Fender {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.type;\n }\n\n case 'preamp': {\n return this.preamp.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preamp.activate();\n } else {\n this.deactivate();\n this.preamp.deactivate();\n }\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n switch (value) {\n case 'marshall': {\n this.type = 'marshall';\n this.preamp = new Marshall(this.context);\n break;\n }\n\n case 'mesa/boogie': {\n this.type = 'mesa/boogie';\n this.preamp = new MesaBoogie(this.context);\n break;\n }\n\n case 'fender': {\n this.type = 'fender';\n this.preamp = new Fender(this.context);\n break;\n }\n }\n\n this.connect();\n }\n\n break;\n }\n\n case 'preamp': {\n if (typeof value === 'object') {\n if (this.preamp instanceof Marshall) {\n const v: MarshallParams = value;\n\n this.preamp.param(v);\n }\n\n if (this.preamp instanceof MesaBoogie) {\n const v: MesaBoogieParams = value;\n\n this.preamp.param(v);\n }\n\n if (this.preamp instanceof Fender) {\n const v: FenderParams = value;\n\n this.preamp.param(v);\n }\n }\n\n break;\n }\n }\n }\n\n return this.preamp;\n }\n\n /** @override */\n public override params(): Required<PreampParams> {\n return {\n state : this.isActive,\n type : this.type,\n preamp: this.preamp.params()\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type ReverbErrorText = 'error' | 'timeout' | 'decode';\n\nexport type ReverbParams = {\n state?: boolean,\n buffer?: number | AudioBuffer | null,\n dry?: number,\n wet?: number,\n tone?: number\n};\n\n/**\n * Effector's subclass for Reverb.\n */\nexport class Reverb extends Effector {\n private convolver: ConvolverNode;\n private dry: GainNode;\n private wet: GainNode;\n private tone: BiquadFilterNode;\n\n private rirs: AudioBuffer[] = [];\n\n // If error occurs at least one, this method aborts the all of connections.\n // Therefore, this flag are shared with the all of `XMLHttpRequest` instances.\n private loadError = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\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 = 'lowpass';\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Reverb) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for reverb effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof ReverbParams|ReverbParams} params This argument is string if getter. Otherwise, setter.\n * @return {ReverbParams[keyof ReverbParams]|Reverb} Return value is parameter for reverb effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'buffer'): AudioBuffer | null;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: ReverbParams): Reverb;\n public param(params: keyof ReverbParams | ReverbParams): ReverbParams[keyof ReverbParams] | Reverb {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'buffer': {\n return this.convolver.buffer;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'buffer': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value < this.rirs.length)) {\n this.convolver.buffer = this.rirs[value];\n this.connect();\n }\n } else if (value instanceof AudioBuffer) {\n this.convolver.buffer = value;\n this.connect();\n } else if (value === null) {\n this.convolver.buffer = null;\n\n // If `buffer` in `ConvolverNode` is `null` after setting instance of `AudioBuffer`, `Reverb` is not OFF (Maybe, it is bug ?)\n // Therefore, `Reverb` is OFF by disconnecting `AudioNode`s.\n this.input.disconnect(0);\n this.input.connect(this.output);\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method sets instance of `AudioBuffer` to `ConvolverNode`.\n * @param {ArrayBuffer|AudioBuffer} impulse This argument is in order to convolve impulse response.\n * This argument is instance of `AudioBuffer` or `ArrayBuffer` for impulse response.\n * @param {function} errorCallback This argument is invoked on decode failure.\n * @return {Reverb} Return value is for method chain.\n */\n public add(impulse: ArrayBuffer | AudioBuffer, errorCallback?: (error: Error) => void): Reverb {\n if (impulse instanceof AudioBuffer) {\n this.convolver.buffer = impulse;\n this.rirs.push(impulse); // Add to preset\n } else if (impulse instanceof ArrayBuffer) {\n const successCallback = (buffer: AudioBuffer) => {\n this.convolver.buffer = buffer;\n this.rirs.push(buffer); // Add to preset\n };\n\n this.context.decodeAudioData(impulse, successCallback, (errorCallback ?? (() => {})));\n }\n\n return this;\n }\n\n /**\n * This method creates and appends to Reverb presets instance of `AudioBuffer` by Ajax.\n * @property {Array<string>|Array<AudioBuffer>} rirs This argument is array that contains URL or instance of `AudioBuffer` for impulse response.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n public preset(params: {\n rirs: string[] | AudioBuffer[];\n timeout?: number;\n successCallback?(event: ProgressEvent): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: ReverbErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { rirs, timeout, successCallback, errorCallback, progressCallback } = params;\n\n for (let index = 0, len = rirs.length; index < len; index++) {\n const rir = rirs[index];\n\n if (typeof rir === 'string') {\n // Get instance of `AudioBuffer` from designated URLs.\n this.load({ rir, index, timeout, successCallback, errorCallback, progressCallback });\n } else {\n // Get instance of `AudioBuffer` directly\n this.rirs[index] = rir;\n }\n }\n }\n\n /** @override */\n public override params(): Required<Omit<ReverbParams, 'buffer'>> {\n return {\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\n /** @override */\n public override activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /** @override */\n public override deactivate() {\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /**\n * This method retrives `ArrayBuffer` and creates instance of `AudioBuffer`.\n * @property {string} url This argument is resource URL for one-shot audio.\n * @property {number} index This argument is in order to assign instance of `AudioBuffer`.\n * @property {number} timeout This argument is Ajax timeout.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n private load(params: {\n rir: string;\n index: number;\n timeout?: number;\n successCallback?(event: ProgressEvent): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: ReverbErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { rir, index, timeout, successCallback, errorCallback, progressCallback } = params;\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'timeout');\n }\n\n this.loadError = true;\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (this.loadError) {\n xhr.abort();\n } else if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'error');\n }\n\n this.loadError = true;\n };\n\n // Success\n xhr.onload = (event: ProgressEvent) => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n const decodeSuccessCallback = (buffer: AudioBuffer) => {\n this.rirs[index] = buffer;\n\n // Creating instance of `AudioBuffer` has completed ?\n for (const rir of this.rirs) {\n if (rir === undefined) {\n return;\n }\n }\n\n if (successCallback) {\n successCallback(event);\n }\n };\n\n const decodeErrorCallback = (error: Error) => {\n if (errorCallback) {\n errorCallback(error, 'decode');\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', rir, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n }\n}\n","import { Effector } from './Effector';\n\nexport type RingmodulatorParams = {\n state?: boolean,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Ring Modulator.\n */\nexport class Ringmodulator extends Effector {\n private amplitude: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.amplitude = context.createGain();\n\n // Initialize parameter\n this.amplitude.gain.value = 0; // 0 +- depth\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Ringmodulator` is not connected by default\n this.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Ring Modulator) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for ring modulator effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof RingmodulatorParams|RingmodulatorParams} params This argument is string if getter. Otherwise, setter.\n * @return {RingmodulatorParams[keyof RingmodulatorParams]|Autopanner} Return value is parameter for ring modulator effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: RingmodulatorParams): Ringmodulator;\n public param(params: keyof RingmodulatorParams | RingmodulatorParams): RingmodulatorParams[keyof RingmodulatorParams] | Ringmodulator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<RingmodulatorParams> {\n return {\n state: this.isActive,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type StereoParams = {\n state?: boolean,\n time?: number\n};\n\n/**\n * Effector's subclass for Stereo.\n */\nexport class Stereo extends Effector {\n public static MAX_DELAY_TIME = 1; // Max delay time is 1000 [ms]\n\n private splitter: ChannelSplitterNode;\n private merger: ChannelMergerNode;\n private delay: DelayNode;\n private gainL: GainNode;\n private gainR: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createChannelMerger(2);\n this.delay = context.createDelay(Stereo.MAX_DELAY_TIME);\n this.gainL = context.createGain();\n this.gainR = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n\n this.gainL.gain.value = +1;\n this.gainR.gain.value = -1;\n\n this.deactivate();\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n this.gainL.disconnect(0);\n this.gainR.disconnect(0);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> ChannelMergerNode\n this.input.connect(this.merger, 0, 0);\n this.input.connect(this.merger, 0, 1);\n\n // GainNode (Input) -> DelayNode -> ChannelSplitterNode -> GainNode (L) / (R) -> ChannelMergerNode -> GainNode (Output)\n this.input.connect(this.delay);\n this.delay.connect(this.splitter);\n this.splitter.connect(this.gainL, 0, 0);\n this.splitter.connect(this.gainR, 1, 0);\n this.gainL.connect(this.merger, 0, 0);\n this.gainR.connect(this.merger, 0, 1);\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.output;\n }\n\n /**\n * This method gets or sets parameters for stereo effector\n * This method is overloaded for type interface and type check.\n * @param {keyof StereoParams|StereoParams} params This argument is string if getter. Otherwise, setter.\n * @return {StereoParams[keyof StereoParams]|Stereo} Return value is parameter for stereo effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: StereoParams): Stereo;\n public param(params: keyof StereoParams | StereoParams): StereoParams[keyof StereoParams] | Stereo {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<StereoParams> {\n return {\n state: this.isActive,\n time : this.delay.delayTime.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type TremoloParams = {\n state?: boolean,\n type?: OscillatorType,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Tremolo.\n */\nexport class Tremolo extends Effector {\n private amplitude: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.amplitude = context.createGain();\n\n // Initialize parameter\n this.amplitude.gain.value = 1; // 1 +- depth\n this.lfo.type = 'sine';\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Tremolo` is not connected by default\n this.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Tremolo) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for tremolo effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof TremoloParams|TremoloParams} params This argument is string if getter. Otherwise, setter.\n * @return {TremoloParams[keyof TremoloParams]|Tremolo} Return value is parameter for tremolo effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'type'): OscillatorType;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: TremoloParams): Tremolo;\n public param(params: keyof TremoloParams | TremoloParams): TremoloParams[keyof TremoloParams] | Tremolo {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.lfo.type;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.lfo.type = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<TremoloParams> {\n return {\n state: this.isActive,\n type : this.lfo.type,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { VocalCancelerParams, VocalCancelerAlgorithm } from '../VocalCanceler';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface VocalCancelerProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n vocalcancelerL: (depth: number, bufferSize: number) => number;\n vocalcancelerR: (depth: number, bufferSize: number) => number;\n vocalcanceler_on_spectrum: (sampleRate: number, minFrequency: number, maxFrequency: number, threshold: number, fftSize: number) => number;\n alloc_memory_inputLs: (bufferSize: number) => number;\n alloc_memory_inputRs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for vocal canceler and Update parameters on message event.\n */\nexport class VocalCancelerProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private algorithm: VocalCancelerAlgorithm = 'time';\n private depth = 0;\n private minFrequency = 200;\n private maxFrequency = 8000;\n private threshold = 0.05;\n\n private isActive = true;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | VocalCancelerParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'algorithm': {\n if (typeof value === 'string') {\n this.algorithm = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth = value;\n }\n\n break;\n }\n\n case 'minFrequency': {\n if (typeof value === 'number') {\n this.minFrequency = value;\n }\n\n break;\n }\n\n case 'maxFrequency': {\n if (typeof value === 'number') {\n this.maxFrequency = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if ((input.length !== 2) || (output.length !== 2)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n if (!this.isActive || (this.depth === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as VocalCancelerProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetInputL = wasm.alloc_memory_inputLs(this.frameSize);\n const offsetInputR = wasm.alloc_memory_inputRs(this.frameSize);\n\n const inputLinearMemoryL = new Float32Array(linearMemory, offsetInputL, this.frameSize);\n const inputLinearMemoryR = new Float32Array(linearMemory, offsetInputR, this.frameSize);\n\n inputLinearMemoryL.set(input[0]);\n inputLinearMemoryR.set(input[1]);\n\n switch (this.algorithm) {\n case 'time': {\n const offsetOutputL = wasm.vocalcancelerL(this.depth, this.frameSize);\n const offsetOutputR = wasm.vocalcancelerR(this.depth, this.frameSize);\n\n output[0].set(new Float32Array(linearMemory, offsetOutputL, this.frameSize));\n output[1].set(new Float32Array(linearMemory, offsetOutputR, this.frameSize));\n\n break;\n }\n\n case 'spectrum': {\n const offsetOutputL = wasm.vocalcanceler_on_spectrum(sampleRate, this.minFrequency, this.maxFrequency, this.threshold, this.frameSize);\n const offsetOutputR = offsetOutputL + (this.frameSize * Float32Array.BYTES_PER_ELEMENT);\n\n const canceledInputLs = new Float32Array(linearMemory, offsetOutputL, this.frameSize);\n const canceledInputRs = new Float32Array(linearMemory, offsetOutputR, this.frameSize);\n\n for (let n = 0; n < this.frameSize; n++) {\n output[0][n] = ((1 - this.depth) * input[0][n]) + (this.depth * canceledInputLs[n]);\n output[1][n] = ((1 - this.depth) * input[1][n]) + (this.depth * canceledInputRs[n]);\n }\n\n break;\n }\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { VocalCancelerProcessor } from './AudioWorkletProcessors/VocalCancelerProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/vocalcanceler.wasm';\n\nexport type VocalCancelerAlgorithm = 'time' | 'spectrum';\n\nexport type VocalCancelerParams = {\n state?: boolean,\n algorithm?: VocalCancelerAlgorithm,\n depth?: number,\n minFrequency?: number,\n maxFrequency?: number,\n threshold?: number\n};\n\n/**\n * This private class is for Vocal Canceler.\n */\nexport class VocalCanceler extends Effector {\n private processor: AudioWorkletNode;\n\n private algorithm: VocalCancelerAlgorithm = 'time';\n private minFrequency = 200;\n private maxFrequency = 8000;\n private threshold = 0.05;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.depth.gain.value = 0;\n\n this.processor = new AudioWorkletNode(this.context, VocalCancelerProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Vocal Canceler) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for vocal canceler.\n * @param {keyof VocalCancelerParams|VocalCancelerParams} params This argument is string if getter. Otherwise, setter.\n * @return {VocalCancelerParams[keyof VocalCancelerParams]|VocalCanceler} Return value is parameter for vocal canceler if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'algorithm'): VocalCancelerAlgorithm;\n public param(params: 'depth'): number;\n public param(params: 'minFrequency'): number;\n public param(params: 'maxFrequency'): number;\n public param(params: 'threshold'): number;\n public param(params: VocalCancelerParams): VocalCanceler;\n public param(params: keyof VocalCancelerParams | VocalCancelerParams): VocalCancelerParams[keyof VocalCancelerParams] | VocalCanceler {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'algorithm': {\n return this.algorithm;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'threshold': {\n return this.threshold;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: VocalCancelerParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'algorithm': {\n if (typeof value === 'string') {\n this.algorithm = value;\n\n const message: VocalCancelerParams = { algorithm: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n\n const message: VocalCancelerParams = { depth: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'minFrequency': {\n if (typeof value === 'number') {\n this.minFrequency = value;\n\n const message: VocalCancelerParams = { minFrequency: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'maxFrequency': {\n if (typeof value === 'number') {\n this.maxFrequency = value;\n\n const message: VocalCancelerParams = { maxFrequency: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n\n const message: VocalCancelerParams = { threshold: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets vocal canceler parameters as associative array.\n * @return {VocalCancelerParams}\n */\n public params(): Required<VocalCancelerParams> {\n return {\n state : this.isActive,\n algorithm : this.algorithm,\n depth : this.depth.gain.value,\n minFrequency: this.minFrequency,\n maxFrequency: this.maxFrequency,\n threshold : this.threshold\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type WahParams = {\n state?: boolean,\n auto?: boolean,\n cutoff?: number,\n depth?: number,\n rate?: number,\n resonance?: number\n};\n\n/**\n * Effector's subclass for Wah.\n */\nexport class Wah extends Effector {\n private auto = false;\n\n private lowpass: BiquadFilterNode;\n private envelopeFollower: WaveShaperNode;\n private sensitivity: BiquadFilterNode;\n\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.lowpass = context.createBiquadFilter();\n this.envelopeFollower = context.createWaveShaper();\n this.sensitivity = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = this.auto ? 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 = 'lowpass';\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\n // `Wah` is not connected by default\n this.deactivate();\n\n this.connect();\n }\n\n /** @override */\n public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (!this.auto && this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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.auto) {\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) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for wah effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof WahParams|WahParams} params This argument is string if getter. Otherwise, setter.\n * @return {WahParams[keyof WahParams]|Wah} Return value is parameter for wah effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'auto'): boolean;\n public param(params: 'cutoff'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'resonance'): number;\n public param(params: WahParams): Wah;\n public param(params: keyof WahParams | WahParams): WahParams[keyof WahParams] | Wah {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'auto': {\n return this.auto;\n }\n\n case 'cutoff': {\n return this.auto ? this.sensitivity.frequency.value : this.lowpass.frequency.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'resonance': {\n return this.auto ? this.sensitivity.Q.value : this.lowpass.Q.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'auto': {\n if (typeof value === 'boolean') {\n this.auto = value;\n this.connect();\n }\n\n break;\n }\n\n case 'cutoff': {\n if (typeof value === 'number') {\n if (this.auto) {\n this.sensitivity.frequency.value = value;\n this.lowpass.frequency.value = 20;\n } else {\n this.lowpass.frequency.value = value;\n }\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.auto ? 10000 * value : this.lowpass.frequency.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'resonance': {\n if (typeof value === 'number') {\n if (this.auto) {\n this.sensitivity.Q.value = value;\n this.lowpass.Q.value = 1;\n } else {\n this.lowpass.Q.value = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<WahParams> {\n return {\n state : this.isActive,\n auto : this.auto,\n cutoff : this.auto ? this.sensitivity.frequency.value : this.lowpass.frequency.value,\n depth : this.auto ? this.depth.gain.value : this.depthRate,\n rate : this.rate.value,\n resonance: this.auto ? this.sensitivity.Q.value : this.lowpass.Q.value\n };\n }\n}\n","import type { Connectable } from '../interfaces';\nimport type { Effector } from './Effectors/Effector';\nimport type { AutopannerParams } from './Effectors/Autopanner';\nimport type { BitCrusherParams } from './Effectors/BitCrusher';\nimport type { ChorusParams } from './Effectors/Chorus';\nimport type { CompressorParams } from './Effectors/Compressor';\nimport type { DelayParams } from './Effectors/Delay';\nimport type { EnvelopeGeneratorParams } from './Effectors/EnvelopeGenerator';\nimport type { EqualizerParams } from './Effectors/Equalizer';\nimport type { FilterParams } from './Effectors/Filter';\nimport type { FlangerParams } from './Effectors/Flanger';\nimport type { FuzzParams } from './Effectors/Fuzz';\nimport type { ListenerParams } from './Effectors/Listener';\nimport type { NoiseGateParams } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressorParams } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDriveParams } from '../SoundModule/Effectors/OverDrive';\nimport type { PannerParams } from './Effectors/Panner';\nimport type { PhaserParams } from './Effectors/Phaser';\nimport type { PitchShifterParams } from './Effectors/PitchShifter';\nimport type { PreampParams } from './Effectors/Preamp';\nimport type { ReverbParams } from './Effectors/Reverb';\nimport type { RingmodulatorParams } from './Effectors/Ringmodulator';\nimport type { StereoParams } from './Effectors/Stereo';\nimport type { TremoloParams } from './Effectors/Tremolo';\nimport type { VocalCancelerParams } from './Effectors/VocalCanceler';\nimport type { WahParams } from './Effectors/Wah';\n\nimport { SoundModuleProcessor } from './SoundModuleProcessor';\nimport { Analyser } from './Analyser';\nimport { Recorder } from './Recorder';\nimport { Autopanner } from './Effectors/Autopanner';\nimport { BitCrusher } from './Effectors/BitCrusher';\nimport { Chorus } from './Effectors/Chorus';\nimport { Compressor } from './Effectors/Compressor';\nimport { Delay } from './Effectors/Delay';\nimport { EnvelopeGenerator } from './Effectors/EnvelopeGenerator';\nimport { Equalizer } from './Effectors/Equalizer';\nimport { Filter } from './Effectors/Filter';\nimport { Flanger } from './Effectors/Flanger';\nimport { Fuzz } from './Effectors/Fuzz';\nimport { Listener } from './Effectors/Listener';\nimport { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport { Panner } from './Effectors/Panner';\nimport { Phaser } from './Effectors/Phaser';\nimport { PitchShifter } from './Effectors/PitchShifter';\nimport { Preamp } from './Effectors/Preamp';\nimport { Reverb } from './Effectors/Reverb';\nimport { Ringmodulator } from './Effectors/Ringmodulator';\nimport { Stereo } from './Effectors/Stereo';\nimport { Tremolo } from './Effectors/Tremolo';\nimport { VocalCanceler } from './Effectors/VocalCanceler';\nimport { Wah } from './Effectors/Wah';\n\nexport type Module =\n Analyser |\n Recorder |\n Autopanner |\n BitCrusher |\n Chorus |\n Compressor |\n Delay |\n EnvelopeGenerator |\n Equalizer |\n Filter |\n Flanger |\n Fuzz |\n Listener |\n NoiseGate |\n NoiseSuppressor |\n OverDrive |\n Panner |\n Phaser |\n PitchShifter |\n Preamp |\n Reverb |\n Ringmodulator |\n Stereo |\n Tremolo |\n VocalCanceler |\n Wah;\n\nexport type ModuleName =\n 'analyser' |\n 'recorder' |\n 'autopanner' |\n 'bitcrusher' |\n 'chorus' |\n 'compressor' |\n 'delay' |\n 'envelopegenerator' |\n 'equalizer' |\n 'filter' |\n 'flanger' |\n 'fuzz' |\n 'listener' |\n 'noisegate' |\n 'noisesuppressor' |\n 'overdrive' |\n 'panner' |\n 'phaser' |\n 'pitchshifter' |\n 'preamp' |\n 'reverb' |\n 'ringmodulator' |\n 'stereo' |\n 'tremolo' |\n 'vocalcanceler' |\n 'wah';\n\nexport type SoundModuleParams = {\n mastervolume?: number,\n autopanner?: AutopannerParams,\n bitcrusher?: BitCrusherParams,\n chorus?: ChorusParams,\n compressor?: CompressorParams,\n delay?: DelayParams,\n envelopegenerator?: EnvelopeGeneratorParams,\n equalizer?: EqualizerParams,\n filter?: FilterParams,\n flanger?: FlangerParams,\n fuzz?: FuzzParams,\n listener?: ListenerParams,\n noisegate?: NoiseGateParams,\n noisesuppressor?: NoiseSuppressorParams,\n overdrive?: OverDriveParams,\n panner?: PannerParams,\n phaser?: PhaserParams,\n pitchshifter?: PitchShifterParams,\n preamp?: PreampParams,\n reverb?: ReverbParams,\n ringmodulator?: RingmodulatorParams,\n stereo?: StereoParams,\n tremolo?: TremoloParams,\n vocalcanceler?: VocalCancelerParams,\n wah?: WahParams\n};\n\nexport { SoundModuleProcessor };\n\n/**\n * This class is superclass that is the top in this library.\n * This class is extended as subclass (`OscillatorModule`, `OneshotModule`, `NoiseModule`, `AudioModule`, `MediaModule`, `StreamModule`, `ProcessorModule`, `MixerModule` ...etc).\n */\nexport abstract class SoundModule implements Connectable {\n public static readonly NUMBER_OF_INPUTS = 2;\n public static readonly NUMBER_OF_OUTPUTS = 2;\n\n protected context: AudioContext;\n protected destination: AudioDestinationNode | MediaStreamAudioDestinationNode;\n\n protected modules: Connectable[] = [];\n\n protected mastervolume: GainNode;\n protected processor: AudioWorkletNode;\n\n protected analyser: Analyser;\n protected recorder: Recorder;\n\n protected autopanner: Autopanner;\n protected bitcrusher: BitCrusher;\n protected chorus: Chorus;\n protected compressor: Compressor;\n protected delay: Delay;\n protected envelopegenerator: EnvelopeGenerator;\n protected equalizer: Equalizer;\n protected filter: Filter;\n protected flanger: Flanger;\n protected fuzz: Fuzz;\n protected listener: Listener;\n protected noisegate: NoiseGate;\n protected noisesuppressor: NoiseSuppressor;\n protected overdrive: OverDrive;\n protected panner: Panner;\n protected phaser: Phaser;\n protected pitchshifter: PitchShifter;\n protected preamp: Preamp;\n protected reverb: Reverb;\n protected ringmodulator: Ringmodulator;\n protected stereo: Stereo;\n protected tremolo: Tremolo;\n protected vocalcanceler: VocalCanceler;\n protected wah: Wah;\n\n protected runningAnalyser = false;\n protected mixed = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n\n this.destination = context.destination;\n\n this.mastervolume = context.createGain();\n this.processor = new AudioWorkletNode(context, SoundModuleProcessor.name);\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context);\n this.autopanner = new Autopanner(context);\n this.bitcrusher = new BitCrusher(context);\n this.chorus = new Chorus(context);\n this.compressor = new Compressor(context);\n this.delay = new Delay(context);\n this.envelopegenerator = new EnvelopeGenerator(context);\n this.equalizer = new Equalizer(context);\n this.filter = new Filter(context);\n this.flanger = new Flanger(context);\n this.fuzz = new Fuzz(context);\n this.listener = new Listener(context);\n this.noisegate = new NoiseGate(context);\n this.noisesuppressor = new NoiseSuppressor(context);\n this.overdrive = new OverDrive(context);\n this.panner = new Panner(context);\n this.phaser = new Phaser(context);\n this.pitchshifter = new PitchShifter(context);\n this.preamp = new Preamp(context);\n this.reverb = new Reverb(context);\n this.ringmodulator = new Ringmodulator(context);\n this.stereo = new Stereo(context);\n this.tremolo = new Tremolo(context);\n this.vocalcanceler = new VocalCanceler(context);\n this.wah = new Wah(context);\n\n // The default order for connection\n this.modules = [\n this.compressor,\n this.wah,\n this.bitcrusher,\n this.overdrive,\n this.fuzz,\n this.preamp,\n this.equalizer,\n this.filter,\n this.pitchshifter,\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 this.autopanner\n ];\n }\n\n /**\n * This method connects `AudioNode`s.\n * @param {AudioNode} source This argument is `AudioNode` as sound source.\n */\n public connect(source: AudioNode): void {\n // Start connection\n // AudioSourceNode (Input)-> AudioNode -> ... -> AudioNode -> GainNode (Master Volume) -> AnalyserNode -> AudioDestinationNode (Output)\n source.disconnect(0); // Clear connection\n\n if (this.modules.length > 0) {\n const input = this.modules[0].INPUT;\n\n if (input === null) {\n return;\n }\n\n source.connect(input);\n } else {\n source.connect(this.mastervolume);\n }\n\n for (let i = 0, len = this.modules.length; i < len; i++) {\n const output = this.modules[i].OUTPUT;\n\n if (output === null) {\n continue;\n }\n\n // Clear connection\n output.disconnect(0);\n\n if (i < (this.modules.length - 1)) {\n const input = this.modules[i + 1].INPUT;\n\n if (input === null) {\n continue;\n }\n\n // Connect to next `AudioNode`\n output.connect(input);\n } else {\n output.connect(this.mastervolume);\n }\n }\n\n this.mastervolume.connect(this.destination);\n\n // for analyser\n this.mastervolume.connect(this.analyser.INPUT);\n\n // for recorder\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.OUTPUT.connect(this.destination);\n }\n\n /**\n * This method disconnects instance of `AudioWorkletNode` as sound source.\n */\n public disconnect(): void {\n this.processor.disconnect(0);\n }\n\n /**\n * This method switches destination over to `AudioDestinationNode`.\n * @return {SoundModule} Return value is for method chain.\n */\n public audioDestination() {\n this.destination = this.context.destination;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method switches destination over to `MediaStreamAudioDestinationNode`.\n * @property {string} sinkId This argument is string as output device ID.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @return {SoundModule} Return value is for method chain.\n */\n public streamDestination(params?: {\n sinkId: string;\n successCallback?: () => void;\n errorCallback?: (error: Error) => void;\n }) {\n this.destination = this.context.createMediaStreamDestination();\n\n if (params?.sinkId) {\n const { sinkId, successCallback, errorCallback } = params;\n\n this.setSinkId(sinkId, successCallback, errorCallback);\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method enables to use multiple output devices.\n * @param {string} sinkId This argument is string as output device ID.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {SoundModule} Return value is for method chain.\n */\n public setSinkId(sinkId: string, successCallback?: () => void, errorCallback?: (error: Error) => void) {\n // @ts-expect-error It is possible that `setSinkId` method is not implemented\n if (this.context.setSinkId) {\n // @ts-expect-error It is possible that `setSinkId` method is not implemented\n this.context.setSinkId(sinkId)\n .then(() => {\n if (typeof successCallback === 'function') {\n successCallback();\n }\n })\n .catch((error: Error) => {\n if (typeof errorCallback === 'function') {\n errorCallback(error);\n }\n });\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method installs customized effector.\n * @param {Effector} effector This argument is subclass that extends `Effector` class.\n * @return {Effector} Return value is instance of customized effector (that extends `Effector` class).\n */\n public install<ExtendedEffector extends Effector>(effector: new (context: AudioContext) => ExtendedEffector): ExtendedEffector {\n const extendedEffector = new effector(this.context);\n\n this.modules.push(extendedEffector);\n\n return extendedEffector;\n }\n\n /**\n * This method starts effectors.\n * @param {number} startTime This argument is used for scheduling parameter.\n * @return {SoundModule} Return value is for method chain.\n */\n public on(startTime?: number) {\n const s = startTime ?? this.context.currentTime;\n\n this.autopanner.start(s);\n this.bitcrusher.start(s);\n this.chorus.start(s);\n this.filter.start(s);\n this.flanger.start(s);\n this.fuzz.start(s);\n this.overdrive.start(s);\n this.phaser.start(s);\n this.ringmodulator.start(s);\n this.tremolo.start(s);\n this.wah.start(s);\n\n // Type inference every subclass\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} Return value is for method chain.\n */\n public off(stopTime?: number) {\n const s = stopTime ?? this.context.currentTime;\n\n this.autopanner.stop(s);\n this.bitcrusher.stop(s);\n this.chorus.stop(s);\n this.filter.stop(s);\n this.flanger.stop(s);\n this.fuzz.stop(s);\n this.overdrive.stop(s);\n this.phaser.stop(s);\n this.ringmodulator.stop(s);\n this.tremolo.stop(s);\n this.wah.stop(s);\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method stops analyser, recorder and `onaudioprocess` event.\n * @return {SoundModule} Return value is for method chain.\n */\n public suspend() {\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n this.runningAnalyser = false;\n\n this.recorder.stop();\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method is invoked on mixing.\n * @return {SoundModule} Return value is for method chain.\n */\n public mix() {\n this.mixed = true;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method is invoked on demixing.\n * @return {SoundModule} Return value is for method chain.\n */\n public demix() {\n this.mixed = false;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {SoundModuleParams}\n */\n public params(): Required<SoundModuleParams> {\n return {\n mastervolume : this.mastervolume.gain.value,\n stereo : this.stereo.params(),\n compressor : this.compressor.params(),\n bitcrusher : this.bitcrusher.params(),\n overdrive : this.overdrive.params(),\n fuzz : this.fuzz.params(),\n preamp : this.preamp.params(),\n wah : this.wah.params(),\n pitchshifter : this.pitchshifter.params(),\n equalizer : this.equalizer.params(),\n filter : this.filter.params(),\n autopanner : this.autopanner.params(),\n tremolo : this.tremolo.params(),\n ringmodulator : this.ringmodulator.params(),\n phaser : this.phaser.params(),\n flanger : this.flanger.params(),\n chorus : this.chorus.params(),\n delay : this.delay.params(),\n reverb : this.reverb.params(),\n panner : this.panner.params(),\n listener : this.listener.params(),\n envelopegenerator: this.envelopegenerator.params(),\n noisegate : this.noisegate.params(),\n noisesuppressor : this.noisesuppressor.params(),\n vocalcanceler : this.vocalcanceler.params()\n };\n }\n\n /**\n * This method edits module to use and module connection order.\n * @param {Array<Connectable>} modules This argument is edited modules.\n * @return {Array<Connectable>} Return value is previous modules.\n */\n public edit(modules: Connectable[]): Connectable[] {\n const previousModules = this.modules;\n\n this.modules = modules;\n\n return previousModules;\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * Connector for input.\n */\n public abstract get INPUT(): GainNode | AudioWorkletNode | null;\n\n /**\n * Connector for output.\n */\n public abstract get OUTPUT(): GainNode;\n\n /**\n * This method re-initials modules.\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n protected init(context: AudioContext): void {\n this.mastervolume.disconnect(0);\n this.processor.disconnect(0);\n this.analyser.INPUT.disconnect(0);\n this.recorder.INPUT.disconnect(0);\n\n for (const module of this.modules) {\n if (module.INPUT) {\n module.INPUT.disconnect(0);\n }\n\n if (module.OUTPUT) {\n module.OUTPUT.disconnect(0);\n }\n }\n\n this.modules.length = 0;\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context);\n this.autopanner = new Autopanner(context);\n this.bitcrusher = new BitCrusher(context);\n this.chorus = new Chorus(context);\n this.compressor = new Compressor(context);\n this.delay = new Delay(context);\n this.envelopegenerator = new EnvelopeGenerator(context);\n this.equalizer = new Equalizer(context);\n this.filter = new Filter(context);\n this.flanger = new Flanger(context);\n this.fuzz = new Fuzz(context);\n this.listener = new Listener(context);\n this.noisegate = new NoiseGate(context);\n this.noisesuppressor = new NoiseSuppressor(context);\n this.overdrive = new OverDrive(context);\n this.panner = new Panner(context);\n this.phaser = new Phaser(context);\n this.pitchshifter = new PitchShifter(context);\n this.preamp = new Preamp(context);\n this.reverb = new Reverb(context);\n this.ringmodulator = new Ringmodulator(context);\n this.stereo = new Stereo(context);\n this.tremolo = new Tremolo(context);\n this.vocalcanceler = new VocalCanceler(context);\n this.wah = new Wah(context);\n\n // The default order for connection\n this.modules = [\n this.compressor,\n this.wah,\n this.bitcrusher,\n this.overdrive,\n this.fuzz,\n this.preamp,\n this.equalizer,\n this.filter,\n this.pitchshifter,\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 this.autopanner\n ];\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class OscillatorModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { Statable } from '../interfaces';\n\nexport type GlideType = 'linear' | 'exponential';\n\nexport type GlideParams = {\n state?: boolean,\n type?: GlideType,\n time?: number\n};\n\n/**\n * This private class is for oscillator glide.\n */\nexport class Glide implements Statable {\n private context: AudioContext;\n\n private type: GlideType = 'linear';\n\n private time = 0; // Glide time\n\n private prevFrequency = -1; // Abnormal value (for the 1st sound)\n private nextFrequency = 0;\n\n private isActive = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n }\n\n /**\n * This method sets frequencies for glide.\n * @param {number} frequency This argument is next frequency for glide.\n */\n public ready(frequency: number): void {\n this.nextFrequency = frequency;\n\n const diff = (this.prevFrequency === -1) ? 0 : (this.nextFrequency - this.prevFrequency);\n\n if (!this.isActive || (this.time === 0) || (diff === 0)) {\n // The 1st sound or Glide OFF or The same sound\n this.prevFrequency = this.nextFrequency;\n }\n }\n\n /**\n * This method starts glide.\n * @param {OscillatorNode} oscillator This argument is instance of `OscillatorNode`.\n * @param {number} startTime This argument is start time for glide.\n */\n public start(oscillator: OscillatorNode, startTime?: number): void {\n const t0 = startTime ?? this.context.currentTime;\n const t1 = t0 + this.time;\n\n // Start glide\n oscillator.frequency.cancelScheduledValues(t0);\n oscillator.frequency.setValueAtTime(this.prevFrequency, t0);\n\n if (this.type === 'exponential') {\n oscillator.frequency.exponentialRampToValueAtTime(this.nextFrequency, t1);\n } else {\n oscillator.frequency.linearRampToValueAtTime(this.nextFrequency, t1);\n }\n }\n\n /**\n * This method stops glide. Moreover, This method prepares for next glide.\n */\n public stop(): void {\n // Stop glide or on the way of glide\n this.prevFrequency = this.nextFrequency;\n }\n\n /**\n * This method gets or sets parameters for glide.\n * @param {keyof GlideParams|GlideParams} params This argument is string if getter. Otherwise, setter.\n * @return {GlideParams[keyof GlideParams]|Glide} Return value is parameter for glide if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): GlideType;\n public param(params: 'time'): number;\n public param(params: GlideParams): Glide;\n public param(params: keyof GlideParams | GlideParams): GlideParams[keyof GlideParams] | Glide {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.type;\n }\n\n case 'time': {\n return this.time;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.type = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.time = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets glide parameters as associative array.\n * @return {GlideParams}\n */\n public params(): Required<GlideParams> {\n return {\n state: this.isActive,\n type : this.type,\n time : this.time\n };\n }\n\n /**\n * This method gets glide state. If returns `true`, glide is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates glide.\n * @return {Glide} Return value is for method chain.\n */\n public activate(): Glide {\n this.isActive = true;\n return this;\n }\n\n /**\n * This method deactivates glide.\n * @return {Glide} Return value is for method chain.\n */\n public deactivate(): Glide {\n this.isActive = false;\n return this;\n }\n}\n","import type { Connectable, Statable } from '../interfaces';\n\nexport type OscillatorCustomType = {\n real: Float32Array,\n imag: Float32Array\n};\n\nexport type OscillatorParams = {\n state?: boolean,\n type?: OscillatorType | OscillatorCustomType,\n octave?: number,\n fine?: number,\n volume?: number\n};\n\n/**\n * This private class is entity for oscillator.\n */\nexport class Oscillator implements Connectable, Statable {\n // 1 Octave = 1200 cent\n public static readonly OCTAVE = 1200 as const;\n\n private context: AudioContext;\n private source: OscillatorNode;\n private volume: GainNode;\n\n private octave = 0;\n private fine = 0;\n private custom: OscillatorCustomType = {\n real: new Float32Array([0, 1]),\n imag: new Float32Array([0, 1])\n };\n\n private isActive: boolean;\n\n // in order to not call in duplicate `start` or `stop` method in instance of `OscillatorNode`\n private paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n * @param {boolean} state This argument is initial state.\n */\n constructor(context: AudioContext, state: boolean) {\n this.context = context;\n this.source = context.createOscillator();\n this.volume = context.createGain();\n\n this.isActive = state;\n }\n\n /**\n * This method connects `AudioNode`s.\n * @param {AudioNode} output This argument is instance of `AudioNode` as output.\n */\n public ready(output: AudioNode): void {\n if (!this.isActive) {\n return;\n }\n\n // Store parameters\n const type = this.source.type;\n const frequency = this.source.frequency.value;\n const detune = this.source.detune.value;\n\n if (!this.paused) {\n this.source.stop(this.context.currentTime);\n this.source.disconnect(0);\n }\n\n this.source = this.context.createOscillator();\n\n if (type === 'custom') {\n // Custom wave\n const reals = this.custom.real;\n const imags = this.custom.imag;\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n } else {\n this.source.type = type;\n }\n\n this.source.frequency.value = frequency;\n this.source.detune.value = detune;\n\n this.volume.connect(output);\n }\n\n /**\n * This method starts sound.\n * @param {number} startTime This argument is start time.\n */\n public start(startTime?: number): void {\n if (this.isActive) {\n this.source.start(startTime ?? this.context.currentTime);\n this.paused = false;\n } else {\n if (!this.paused) {\n this.source.stop(this.context.currentTime);\n this.paused = true;\n }\n\n this.source.disconnect(0);\n }\n }\n\n /**\n * This method stops sound.\n * @param {number} stopTime This argument is stop time.\n */\n public stop(stopTime?: number): void {\n if (this.paused) {\n return;\n }\n\n this.source.stop(stopTime ?? this.context.currentTime);\n this.source.disconnect(0);\n\n this.paused = true;\n }\n\n /**\n * This method gets or sets parameters for oscillator.\n * @param {keyof OscillatorParams|OscillatorParams} params This argument is string if getter. Otherwise, setter.\n * @return {OscillatorParams[keyof OscillatorParams]} Return value is parameter for oscillator if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): OscillatorType | OscillatorCustomType;\n public param(params: 'octave'): number;\n public param(params: 'fine'): number;\n public param(params: 'volume'): number;\n public param(params: OscillatorParams): Oscillator;\n public param(params: keyof OscillatorParams | OscillatorParams): OscillatorParams[keyof OscillatorParams] | Oscillator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.source.type;\n }\n\n case 'octave': {\n return this.octave;\n }\n\n case 'fine': {\n return this.fine;\n }\n\n case 'volume': {\n return this.volume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.source.type = value;\n } else if (typeof value === 'object') {\n let { real, imag } = value;\n\n const MAX_SIZE = 4096; // This size is defined by specification\n\n if (real.length > MAX_SIZE) { real = real.subarray(0, MAX_SIZE); }\n if (imag.length > MAX_SIZE) { imag = imag.subarray(0, MAX_SIZE); }\n\n // The 1st value is fixed by 0 (This is is defined by specification)\n if (real[0] !== 0) { real[0] = 0; }\n if (imag[0] !== 0) { imag[0] = 0; }\n\n const periodicWave = this.context.createPeriodicWave(real, imag);\n\n this.source.setPeriodicWave(periodicWave);\n\n this.custom.real = real;\n this.custom.imag = imag;\n }\n\n break;\n }\n\n case 'octave': {\n if (typeof value === 'number') {\n this.octave = value;\n this.source.detune.value = this.fine + (value * Oscillator.OCTAVE);\n }\n\n break;\n }\n\n case 'fine': {\n if (typeof value === 'number') {\n this.fine = value;\n this.source.detune.value = value + (this.octave * Oscillator.OCTAVE);\n }\n\n break;\n }\n\n case 'volume': {\n if (typeof value === 'number') {\n this.volume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `OscillatorNode`.\n * @return {OscillatorNode}\n */\n public get(): OscillatorNode {\n return this.source;\n }\n\n /** @override */\n public state(): boolean {\n return this.isActive;\n }\n\n /** @override */\n public activate(): Oscillator {\n this.isActive = true;\n return this;\n }\n\n /** @override */\n public deactivate(): Oscillator {\n this.isActive = false;\n return this;\n }\n\n /**\n * This method gets oscillator parameters as associative array.\n * @return {OscillatorParams}\n */\n public params(): Required<OscillatorParams> {\n return {\n state : this.isActive,\n type : this.source.type,\n octave: this.octave,\n fine : this.fine,\n volume: this.volume.gain.value\n };\n }\n\n /** @override */\n public get INPUT(): OscillatorNode {\n return this.source;\n }\n\n /** @override */\n public get OUTPUT(): GainNode {\n return this.volume;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { OscillatorParams, OscillatorCustomType } from './Oscillator';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\nimport type { GlideParams, GlideType } from './Glide';\n\nimport { SoundModule } from '../SoundModule';\nimport { OscillatorModuleProcessor } from './OscillatorModuleProcessor';\nimport { Glide } from './Glide';\nimport { Oscillator } from './Oscillator';\n\nexport type {\n Glide,\n GlideParams,\n GlideType,\n Oscillator,\n OscillatorParams,\n OscillatorCustomType\n};\n\nexport { OscillatorModuleProcessor };\n\nexport type OscillatorModuleParams = SoundModuleParams & {\n oscillator?: {\n glide: GlideParams,\n params: OscillatorParams[]\n }\n};\n\n/**\n * This class manages instances of `Oscillator` for creating sound.\n */\nexport class OscillatorModule extends SoundModule {\n private sources: Oscillator[] = [];\n private glide: Glide;\n\n private startTime = 0;\n private duration = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, OscillatorModuleProcessor.name);\n this.glide = new Glide(context);\n }\n\n /**\n * This method creates instances of `Oscillator`.\n * @param {Array<boolean>} states This argument is array that contains initial state in instance of `Oscillator`.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public setup(states: boolean[]): OscillatorModule {\n // Clear\n this.sources.length = 0;\n\n for (let i = 0, len = states.length; i < len; i++) {\n this.sources[i] = new Oscillator(this.context, states[i]);\n this.envelopegenerator.setGenerator(i);\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 start time. The default value is `currentTime` in instance of `AudioContext`\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public ready(startTime?: number, duration?: number): OscillatorModule {\n this.startTime = startTime ?? this.context.currentTime;\n this.duration = duration ?? 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>} frequencies This argument each oscillator frequency. The default value is 0 Hz.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public start(frequencies: number[]): OscillatorModule {\n const startTime = this.context.currentTime + this.startTime;\n\n if (!this.mixed) {\n // Clear previous\n this.envelopegenerator.clear(true);\n\n // AudioWorkletNode (Mix oscillators) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n }\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) -> AudioWorkletNode (Mix oscillators)\n oscillator.ready(this.processor);\n\n // OscillatorNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume)\n this.envelopegenerator.ready(i, oscillator.INPUT, oscillator.OUTPUT);\n\n this.glide.ready(frequency);\n this.glide.start(oscillator.INPUT, 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.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method stops active sounds.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public stop(): OscillatorModule {\n const stopTime = this.context.currentTime + this.startTime + this.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime, false);\n\n this.glide.stop();\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for oscillator module.\n * This method is overloaded for type interface and type check.\n * @param {keyof OscillatorModuleParams|OscillatorModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {OscillatorModuleParams[keyof OscillatorModuleParams]|OscillatorModule} Return value is parameter for oscillator module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: OscillatorModuleParams): OscillatorModule;\n public param(params: keyof OscillatorModuleParams | OscillatorModuleParams): OscillatorModuleParams[keyof OscillatorModuleParams] | OscillatorModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Oscillator` or array that contains the all of `Oscillator`s.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `Oscillator`.\n * @return {Oscillator|Array<Oscillator>}\n */\n public get(index: number): Oscillator;\n public get(): Oscillator[];\n public get(index?: number): Oscillator | Oscillator[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.sources.length)) {\n return this.sources[index];\n }\n\n return this.sources;\n }\n\n /**\n * This method returns the number of `Oscillator`s.\n * @return {number}\n */\n public length(): number {\n return this.sources.length;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName|'glide'} moduleName This argument selects module.\n * @return {Module|Glide}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: 'glide'): Glide;\n public module(moduleName: ModuleName | 'glide'): Module | Glide {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n\n case 'glide': {\n return this.glide;\n }\n }\n }\n\n /**\n * This method gets oscillator module parameters as associative array.\n * @return {OscillatorModuleParams}\n * @override\n */\n public override params(): Required<OscillatorModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n oscillator: {\n glide : this.glide.params(),\n params: this.sources.map((source: Oscillator) => {\n return source.params();\n })\n }\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class OneshotModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { OneshotModuleProcessor } from './OneshotModuleProcessor';\n\nexport type OneshotErrorText = 'error' | 'timeout' | 'decode';\n\nexport type OneshotSetting = {\n bufferIndex: number,\n playbackRate?: number,\n loop?: boolean,\n loopStart?: number,\n loopEnd?: number,\n volume?: number\n};\n\nexport type OneshotSettings = OneshotSetting[];\n\nexport type OneshotModuleParams = SoundModuleParams & {\n transpose?: number\n};\n\nexport { OneshotModuleProcessor };\n\n/**\n * This subclass is for playing one-shot audio\n */\nexport class OneshotModule extends SoundModule {\n private sources: AudioBufferSourceNode[] = [];\n private resources: string[] | AudioBuffer[] = [];\n private buffers: AudioBuffer[] = [];\n private volumes: GainNode[] = [];\n private states: boolean[] = [];\n private settings: OneshotSettings = [];\n\n private startTime = 0;\n private duration = 0;\n\n private transpose = 0;\n\n // If error occurs at least one, this method aborts the all of connections.\n // Therefore, this flag are shared with the all of `XMLHttpRequest` instances.\n private loadError = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, OneshotModuleProcessor.name);\n }\n\n /**\n * This method creates instances of `AudioBuffer` by Ajax.\n * @property {Array<string>|Array<AudioBuffer>} resources This argument is array that contains URL or instance of `AudioBuffer` for audio resources.\n * @property {OneshotSettings} settings This argument is settings (such as `playbackRate`, `loop` ... etc) each audio sources.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success;\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n * @property {OneshotModule} Return value is for method chain.\n */\n public setup(params: {\n resources: string[] | AudioBuffer[];\n settings: OneshotSettings;\n timeout?: number;\n successCallback?(event: ProgressEvent, buffers: AudioBuffer[]): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: OneshotErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): OneshotModule {\n const { resources, settings, timeout, successCallback, errorCallback, progressCallback } = params;\n\n for (let i = 0, len = settings.length; i < len; i++) {\n this.states[i] = false;\n this.volumes[i] = this.context.createGain();\n this.settings[i] = settings[i];\n\n this.envelopegenerator.setGenerator(i);\n }\n\n for (let index = 0, len = resources.length; index < len; index++) {\n this.resources[index] = resources[index];\n\n const url = this.resources[index];\n\n if (typeof url === 'string') {\n // Get instance of `AudioBuffer` from designated URL.\n this.load({ url, index, timeout, successCallback, errorCallback, progressCallback });\n } else {\n this.buffers[index] = url;\n }\n }\n\n return this;\n }\n\n /**\n * This method schedules playing audio.\n * @param {number} startTime This argument is start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OneshotModule} Return value is for method chain.\n */\n public ready(startTime?: number, duration?: number): OneshotModule {\n this.startTime = startTime ?? 0;\n this.duration = duration ?? 0;\n\n this.envelopegenerator.clear(false);\n\n return this;\n }\n\n /**\n * This method starts one-shot audio.\n * @param {Array<number>} indexes This argument selects instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} Return value is for method chain.\n */\n public start(indexes: number[]): OneshotModule {\n const startTime = this.context.currentTime + this.startTime;\n\n if (!this.mixed) {\n this.envelopegenerator.clear(false);\n\n // AudioWorkletNode (Mix one-shots) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n }\n\n for (const index of indexes) {\n if ((index < 0) || (index >= this.settings.length)) {\n continue;\n }\n\n const { bufferIndex, playbackRate, loop, loopStart, loopEnd, volume } = this.settings[index];\n\n // The following code is unnecessary, because `AudioBufferSourceNode` is the target of garbage collection in case of no references and no sound\n // (If there is this code, application cannot repeat hits).\n\n // if (this.sources[index]) {\n // this.sources[index].stop(this.context.currentTime);\n // this.sources[index].disconnect(0);\n // }\n\n const source = this.context.createBufferSource();\n\n source.buffer = this.buffers[bufferIndex];\n\n source.playbackRate.value = playbackRate ?? 1;\n source.detune.value = this.transpose * 100;\n source.loop = loop ?? false;\n source.loopStart = loopStart ?? 0;\n source.loopEnd = loopEnd ?? source.buffer.duration;\n\n this.volumes[index].gain.value = volume ?? 1;\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume) -> AudioWorkletNode (Mix one-shots)\n this.envelopegenerator.ready(index, source, this.volumes[index]);\n this.volumes[index].connect(this.processor);\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[index] = source;\n\n this.states[index] = true;\n }\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method stops one-shot audio.\n * @param {Array<number>} indexes This argument selects instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} Return value is for method chain.\n */\n public stop(indexes: number[]): OneshotModule {\n const stopTime = this.context.currentTime + this.startTime + this.duration;\n\n indexes.forEach((index: number) => {\n if (this.states[index]) {\n this.sources[index].stop(stopTime);\n\n this.states[index] = false;\n }\n });\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n this.envelopegenerator.clear(false);\n\n this.off(stopTime);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for one-shot module.\n * This method is overloaded for type interface and type check.\n * @param {keyof OneshotModuleParams|OneshotModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {OneshotModuleParams[keyof OneshotModuleParams]|OneshotModule} Return value is parameter for one-shot module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'transpose'): number;\n public param(params: OneshotModuleParams): OneshotModule;\n public param(params: keyof OneshotModuleParams | OneshotModuleParams): OneshotModuleParams[keyof OneshotModuleParams] | OneshotModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'transpose': {\n return this.transpose;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'transpose': {\n if (typeof value === 'number') {\n this.transpose = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AudioBuffer` or array that contains the all of `AudioBuffer`s.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `AudioBuffer`.\n * @return {AudioBuffer|AudioBuffer[]}\n */\n public get(index: number): AudioBuffer;\n public get(): AudioBuffer[];\n public get(index?: number): AudioBuffer | AudioBuffer[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.buffers.length)) {\n return this.buffers[index];\n }\n\n return this.buffers;\n }\n\n /**\n * This method resets settings.\n * @param {number} index This argument selects target setting.\n * @param {keyof OneshotSetting} paramName This argument is one-shot parameter name.\n * @param {OneshotSetting} param This argument is one-shot parameter value.\n * @return {OneshotModule} Return value is for method chain.\n */\n public reset(index: number, paramName: keyof OneshotSetting, param: number | boolean): OneshotModule {\n if ((index >= 0) && (index < this.settings.length)) {\n switch (paramName) {\n case 'bufferIndex' :\n case 'playbackRate':\n case 'loopStart' :\n case 'loopEnd' :\n case 'volume' : {\n if (typeof param === 'number') {\n this.settings[index][paramName] = param;\n }\n\n break;\n }\n\n case 'loop': {\n if (typeof param === 'boolean') {\n this.settings[index][paramName] = param;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets one-shot module parameters as associative array.\n * @return {OneshotModuleParams}\n * @override\n */\n public override params(): Required<OneshotModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n transpose: this.transpose\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates instance of `AudioBuffer`.\n * @property {string} url This argument is resource URL for one-shot audio.\n * @property {number} index This argument is in order to assign instance of `AudioBuffer`.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success;\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n private load(params: {\n url: string;\n index: number;\n timeout?: number;\n successCallback?(event: ProgressEvent, buffers: AudioBuffer[]): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: OneshotErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { url, index, timeout, successCallback, errorCallback, progressCallback } = params;\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'timeout');\n }\n\n this.loadError = true;\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (this.loadError) {\n xhr.abort();\n } else if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'error');\n }\n\n this.loadError = true;\n };\n\n // Success\n xhr.onload = (event: ProgressEvent) => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = (buffer: AudioBuffer) => {\n this.buffers[index] = buffer;\n\n // Creating instance of `AudioBuffer` has completed ?\n for (const buffer of this.buffers) {\n if (buffer === undefined) {\n return;\n }\n }\n\n if (successCallback) {\n successCallback(event, this.buffers);\n }\n };\n\n const decodeErrorCallback = (error: Error) => {\n if (errorCallback) {\n errorCallback(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';\n xhr.send(null);\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\nimport type { NoiseType, NoiseModuleParams } from './';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\ninterface NoiseModuleProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n whitenoise: (frame: number) => number;\n pinknoise: (frame: number) => number;\n browniannoise: (frame: number) => number;\n};\n\nexport type NoiseProcessingMessageEventData = {\n processing?: boolean;\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for generating noise.\n */\nexport class NoiseModuleProcessor extends AudioWorkletProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private processing = false;\n\n private type: NoiseType = 'whitenoise';\n\n constructor() {\n super();\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | (NoiseModuleParams & NoiseProcessingMessageEventData)>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n if (typeof event.data.processing === 'boolean') {\n this.processing = event.data.processing;\n }\n\n if (event.data.type) {\n this.type = event.data.type;\n }\n }\n };\n }\n\n /** @override */\n protected override process(_inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n if (!this.processing) {\n // Prevent from calling private method for noise processor if not active\n return true;\n }\n\n const output = outputs[0];\n\n // HACK:\n const wasm = this.instance.exports as NoiseModuleProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0, numberOfChannels = output.length; channelNumber < numberOfChannels; channelNumber++) {\n const bufferSize = output[channelNumber].length;\n\n switch (this.type) {\n case 'whitenoise': {\n const offsetOutput = wasm.whitenoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n\n case 'pinknoise': {\n const offsetOutput = wasm.pinknoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n\n case 'browniannoise': {\n const offsetOutput = wasm.browniannoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n }\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { NoiseProcessingMessageEventData } from './NoiseModuleProcessor';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { NoiseModuleProcessor } from './NoiseModuleProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './WebAssemblyModules/noisegenerator.wasm';\n\nexport type NoiseType = 'whitenoise' | 'pinknoise' | 'browniannoise';\n\nexport type NoiseModuleParams = SoundModuleParams & {\n type?: NoiseType\n};\n\nexport { NoiseModuleProcessor };\n\n/**\n * This subclass is for generating noise.\n */\nexport class NoiseModule extends SoundModule {\n private type: NoiseType = 'whitenoise';\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, NoiseModuleProcessor.name);\n\n this.envelopegenerator.setGenerator(0);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /**\n * This method defines noop for the same API.\n */\n public setup(): NoiseModule {\n // Noop\n return this;\n }\n\n /**\n * This method defines noop for the same API.\n */\n public ready(): NoiseModule {\n // Noop\n return this;\n }\n\n /**\n * This method starts noise.\n * @return {NoiseModule} Return value is for method chain.\n */\n public start(): NoiseModule {\n const startTime = this.context.currentTime;\n\n if (!this.mixed) {\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n this.connect(generator);\n }\n }\n\n this.envelopegenerator.ready(0, this.processor, null);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n this.on(startTime);\n\n const message: NoiseProcessingMessageEventData = { processing: true };\n\n this.processor.port.postMessage(message);\n\n return this;\n }\n\n /**\n * This method stops noise.\n * @return {NoiseModule} Return value is for method chain.\n */\n public stop(): NoiseModule {\n const stopTime = this.context.currentTime;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.off(stopTime);\n\n const message: NoiseProcessingMessageEventData = { processing: false };\n\n this.processor.port.postMessage(message);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for noise module.\n * @param {keyof NoiseModuleParams|NoiseModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseModuleParams[keyof NoiseModuleParams]|NoiseModule} Return value is parameter for noise module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'type'): NoiseType;\n public param(params: NoiseModuleParams): NoiseModule;\n public param(params: keyof NoiseModuleParams | NoiseModuleParams): NoiseModuleParams[keyof NoiseModuleParams] | NoiseModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'type': {\n return this.type;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'whitenoise') || (value === 'pinknoise') || (value === 'browniannoise')) {\n this.type = value;\n\n const message: NoiseModuleParams = { type: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override disconnect() {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n generator.disconnect(0);\n }\n }\n\n /**\n * This method gets noise module parameters as associative array.\n * @return {NoiseModuleParams}\n * @override\n */\n public override params(): Required<NoiseModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n type: this.type\n };\n }\n\n /** @override */\n public override get INPUT(): GainNode | null {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n return generator;\n }\n\n return null;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class AudioModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length > 0) && (input[0].length > 0)) {\n if ((currentFrame % 16384) === 0) {\n // Fire `onmessage` event (that main thread has) every `16384` samples\n this.port.postMessage({});\n }\n }\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { AudioModuleProcessor } from './AudioModuleProcessor';\n\nexport type AudioBufferSprite = { [spriteName: string]: AudioBuffer };\n\nexport type AudioModuleParams = SoundModuleParams & {\n playbackRate?: number,\n detune?: number,\n speed?: number,\n loop?: boolean,\n currentTime?: number,\n readonly duration?: number,\n readonly sampleRate?: number,\n readonly numberOfChannels?: number\n};\n\nexport { AudioModuleProcessor };\n\n/**\n * This subclass is for playing single audio.\n * This class enables to create audio player that has higher features than `HTMLAudioElement`.\n * But, this class is disadvantage to play many one shot audios.\n * In that case, developer should use `OneshotModule`.\n */\nexport class AudioModule extends SoundModule {\n private source: AudioBufferSourceNode;\n private buffer: AudioBuffer | null = null;\n\n private currentTime = 0;\n private stopped = true;\n\n private speed = 1;\n\n private decodeCallback?(buffer: AudioBuffer): void;\n private updateCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n private endedCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n private errorCallback?(error: Error): void;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, AudioModuleProcessor.name);\n\n this.source = context.createBufferSource();\n }\n\n /**\n * This method sets up envelope generator for fade-in and fade-out.\n * @return {AudioModule} Return value is for method chain.\n */\n public setup(callbacks?: {\n decodeCallback?(buffer: AudioBuffer): void;\n updateCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n endedCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n errorCallback?(error: Error): void;\n }): AudioModule {\n const { decodeCallback, updateCallback, endedCallback, errorCallback } = callbacks ?? {};\n\n if (decodeCallback) {\n this.decodeCallback = decodeCallback;\n }\n\n if (updateCallback) {\n this.updateCallback = updateCallback;\n }\n\n if (endedCallback) {\n this.endedCallback = endedCallback;\n }\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\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 decodes instance of `ArrayBuffer` to `ArrayBuffer` or sets instanceof `AudioBuffer`.\n * @param {ArrayBuffer|AudioBuffer} buffer This argument is instance of `ArrayBuffer` or `AudioBuffer`.\n * If this is `ArrayBuffer`, this method executes decode.\n * @return {AudioModule} Return value is for method chain.\n */\n public ready(buffer: ArrayBuffer | AudioBuffer): AudioModule {\n if (buffer instanceof ArrayBuffer) {\n this.buffer = null;\n\n const successCallback = (audiobuffer: AudioBuffer) => {\n this.buffer = audiobuffer;\n\n this.analyser.start('timeoverview', 0, this.buffer);\n this.analyser.start('timeoverview', 1, this.buffer);\n\n if (this.decodeCallback) {\n this.decodeCallback(this.buffer);\n }\n };\n\n this.context.decodeAudioData(buffer, successCallback, this.errorCallback);\n } else if (buffer instanceof AudioBuffer) {\n this.buffer = buffer;\n }\n\n return this;\n }\n\n /**\n * This method starts audio from designated time.\n * @param {number} startTime This argument is time that audio is started at. The default value is `0`.\n * @param {number} endTime This argument is time that audio is ended at. The default value is audio duration.\n * @return {AudioModule} This is returned for method chain.\n */\n public start(startTime?: number, endTime?: number): AudioModule {\n if ((this.buffer === null) || !this.stopped) {\n return this;\n }\n\n const currentTime = this.context.currentTime;\n\n const start = startTime ?? 0;\n const end = endTime ?? this.buffer.duration;\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 detune = this.source.detune.value;\n const loop = this.source.loop;\n\n this.source = this.context.createBufferSource();\n\n this.source.buffer = this.buffer;\n this.source.playbackRate.value = playbackRate;\n this.source.detune.value = detune;\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) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor);\n\n const computedPlaybackRate = this.computePlaybackRate();\n\n 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', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.stopped = false;\n\n this.envelopegenerator.start(currentTime);\n\n if (end >= 0) {\n this.envelopegenerator.stop((currentTime + ((end - start) / computedPlaybackRate)), true);\n } else {\n this.envelopegenerator.stop((currentTime + ((this.buffer.duration - start) / computedPlaybackRate)), true);\n }\n\n this.on(currentTime);\n\n const timeoverviewL = this.analyser.domain('timeoverview', 0);\n const timeoverviewR = this.analyser.domain('timeoverview', 1);\n\n // Invoke `onmessage` event handler every `16384` samples and update UI\n this.processor.port.onmessage = () => {\n if (this.buffer === null) {\n this.end();\n return;\n }\n\n if (Math.abs(this.source.loopEnd - this.currentTime) > 0.5) {\n const playbackRate = this.computePlaybackRate();\n\n this.currentTime += ((16384 / this.buffer.sampleRate) * playbackRate);\n\n if (this.updateCallback) {\n this.updateCallback(this.source, this.currentTime);\n }\n\n timeoverviewL.update(this.currentTime);\n timeoverviewR.update(this.currentTime);\n } else {\n if (this.source.loop) {\n this.stop();\n\n if (timeoverviewL.param('mode') === 'sprite') {\n this.start(this.source.loopStart, this.source.loopEnd);\n } else {\n this.start(0, this.buffer.duration);\n }\n } else {\n this.end();\n }\n }\n };\n\n return this;\n }\n\n /**\n * This method stops audio.\n * @return {AudioModule} Return value is for method chain.\n */\n public stop(): AudioModule {\n if ((this.buffer === null) || this.stopped) {\n return this;\n }\n\n const stopTime = this.context.currentTime;\n\n this.source.stop(stopTime);\n\n this.off(stopTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n // Clear\n this.stopped = true;\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for audio module.\n * This method is overloaded for type interface and type check.\n * @param {keyof AudioModuleParams|AudioModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {AudioModuleParams[keyof AudioModuleParams]|AudioModule} Return value is parameter for audio module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'playbackRate'): number;\n public param(params: 'detune'): number;\n public param(params: 'speed'): number;\n public param(params: 'loop'): boolean;\n public param(params: 'currentTime'): number;\n public param(params: 'duration'): number;\n public param(params: 'sampleRate'): number;\n public param(params: 'numberOfChannels'): number;\n public param(params: 'numberOfChannels'): number;\n public param(params: AudioModuleParams): AudioModule;\n public param(params: keyof AudioModuleParams | AudioModuleParams): AudioModuleParams[keyof AudioModuleParams] | AudioModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'playbackRate': {\n return this.source.playbackRate.value;\n }\n\n case 'detune': {\n return this.source.detune.value;\n }\n\n case 'speed': {\n return this.speed;\n }\n\n case 'loop': {\n return this.source.loop;\n }\n\n case 'currentTime': {\n return this.currentTime;\n }\n\n case 'duration': {\n return this.source.buffer?.duration ?? 0; // Getter only\n }\n\n case 'sampleRate': {\n return this.source.buffer?.sampleRate ?? this.context.sampleRate; // Getter only\n }\n\n case 'numberOfChannels': {\n return this.source.buffer?.numberOfChannels ?? 0; // Getter only\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'playbackRate': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.source.playbackRate.value = value;\n\n const playbackRate = this.computePlaybackRate();\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n }\n }\n\n break;\n }\n\n case 'detune': {\n if (typeof value === 'number') {\n this.source.detune.value = value;\n\n const playbackRate = this.computePlaybackRate();\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.speed = value;\n\n const pitch = this.pitchshifter.param('pitch');\n\n this.pitchshifter.param({ pitch: pitch, speed: this.speed });\n\n this.source.playbackRate.value = this.speed;\n\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / this.speed)), true);\n }\n }\n\n break;\n }\n\n case 'loop': {\n if (typeof value === 'boolean') {\n this.source.loop = value;\n }\n\n break;\n }\n\n case 'currentTime': {\n if (typeof value === 'number') {\n this.currentTime = value;\n\n if (!this.stopped) {\n this.stop();\n this.start(value);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AudioBufferSourceNode`.\n * @return {AudioBufferSourceNode}\n */\n public get(): AudioBufferSourceNode {\n return this.source;\n }\n\n /**\n * This method rewinds audio.\n * @return {AudioModule} Return value is for method chain.\n */\n public end(): AudioModule {\n this.stop();\n this.currentTime = 0;\n\n if (this.endedCallback) {\n this.endedCallback(this.source, 0);\n }\n\n return this;\n }\n\n /**\n * This method determines whether instance of `AudioBuffer` exists.\n * @return {boolean} If instance of `AudioBuffer` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.buffer !== null;\n }\n\n /**\n * This method determines whether audio is paused.\n * @return {boolean} If audio is paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return this.stopped;\n }\n\n /**\n * This method gets or sets 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} Return value is fade-in time. Otherwise, return value is for method chain.\n */\n public fadeIn(time?: number): number | AudioModule {\n if (typeof time !== 'number') {\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.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n const playbackRate = this.computePlaybackRate();\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 gets or sets 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} Return value is fade-out time. Otherwise, return value is for method chain.\n */\n public fadeOut(time?: number): number | AudioModule {\n if (typeof time !== 'number') {\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.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n const playbackRate = this.computePlaybackRate();\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 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} Return value is sliced `AudioBuffer`.\n */\n public slice(startTime?: number, endTime?: number): AudioBuffer | null {\n if (this.buffer === null) {\n return null;\n }\n\n const duration = this.buffer.duration;\n const sampleRate = this.buffer.sampleRate;\n const numberOfChannels = this.buffer.numberOfChannels;\n\n const start = Math.trunc((startTime ?? 0) * sampleRate);\n const end = Math.trunc((endTime ?? duration) * sampleRate);\n\n const dataLs = (numberOfChannels > 0) ? this.buffer.getChannelData(0) : null;\n const dataRs = (numberOfChannels > 1) ? this.buffer.getChannelData(1) : null;\n\n const bufferSize = end - start;\n\n switch (numberOfChannels) {\n case 1: {\n if (dataLs === null) {\n return null;\n }\n\n const bufferLs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n }\n\n const buffer = this.context.createBuffer(1, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n\n return buffer;\n }\n\n case 2: {\n if ((dataLs === null) || (dataRs === null)) {\n return null;\n }\n\n const bufferLs = new Float32Array(bufferSize);\n const 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 const buffer = this.context.createBuffer(2, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n buffer.copyToChannel(bufferRs, 1);\n\n return buffer;\n }\n }\n\n return null;\n }\n\n /**\n * This method sprites audio.\n * @param {Object.<string, Array<number>>} sprites This argument is associative array that contains sprite times.\n * @return {AudioBufferSprite} Return value is associative array that contains sprited `AudioBuffer`.\n */\n public sprite(sprites: { [spriteName: string]: [number, number] }): AudioBufferSprite | null {\n if (this.buffer === null) {\n return null;\n }\n\n return Object.keys(sprites).reduce((audioSprite: AudioBufferSprite, spriteName: string) => {\n const times: [number, number] = sprites[spriteName];\n\n const audiobuffer = this.slice(...times);\n\n if (audiobuffer !== null) {\n audioSprite[spriteName] = audiobuffer;\n }\n\n return audioSprite;\n }, {});\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets audio module parameters as associative array.\n * @return {AudioModuleParams}\n * @override\n */\n public override params(): Required<AudioModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n playbackRate : this.source.playbackRate.value,\n detune : this.source.detune.value,\n speed : this.speed,\n loop : this.source.loop,\n currentTime : this.currentTime,\n duration : this.buffer?.duration ?? 0,\n sampleRate : this.buffer?.sampleRate ?? this.context.sampleRate,\n numberOfChannels: this.buffer?.numberOfChannels ?? 0,\n vocalcanceler : this.vocalcanceler.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method returns computed playback rate from `playbackRate` and `detune` that `AudioBufferSourceNode` has (@see https://www.w3.org/TR/webaudio/#computedplaybackrate)\n * @return {number} Return value is computed playback rate.\n */\n private computePlaybackRate(): number {\n return this.source.playbackRate.value * (2 ** (this.source.detune.value / 1200));\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class MediaModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { MediaModuleProcessor } from './MediaModuleProcessor';\n\nexport type MediaModuleParams = SoundModuleParams & {\n autoplay?: boolean,\n playbackRate?: number,\n currentTime?: number,\n controls?: boolean,\n loop?: boolean,\n muted?: boolean,\n readonly duration?: number\n};\n\nexport { MediaModuleProcessor };\n\n/**\n * This class processes sound data from `HTMLMediaElement`.\n * Namely, this class enables to create audio player that has higher features from `HTMLMediaElement`.\n * But, this class is disadvantage to play many one shot audios.\n * In that case, developer should use `OneshotModule`.\n */\nexport class MediaModule extends SoundModule {\n private source: MediaElementAudioSourceNode | null = null;\n private media: HTMLAudioElement | HTMLVideoElement | null = null;\n\n // 'wav', 'ogg', 'mp3, 'webm', 'ogv', 'mp4' ...etc\n private ext = '';\n\n // for Autoplay policy\n private autoplay = false;\n\n // for Audio Streaming\n private mediaSource: MediaSource | null = null;\n private sourceBuffer: SourceBuffer | null = null;\n private file = '';\n private mimeType = '';\n\n // Keys are 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 private listeners: { [eventType: string]: (event: Event | Error) => void } = {};\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, MediaModuleProcessor.name);\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.onSourceBufferUpdateEnd = this.onSourceBufferUpdateEnd.bind(this);\n this.onSourceBufferError = this.onSourceBufferError.bind(this);\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 * @property {HTMLAudioElement|HTMLVideoElement} media This argument is either `HTMLAudioElement` or `HTMLVideoElement`.\n * @property {Array<string>} formats This argument is usable media format. For example, 'wav', 'ogg', 'webm', 'mp4' ...etc.\n * @property {boolean} autoplay This argument is in order to determine autoplay. The default value is `false`.\n * @property {{ [eventType: string]: (event: Event | Error) => void }} listeners This argument is event listeners that are defined by `HTMLMediaElement`.\n * @return {MediaModule} Return value is for method chain.\n */\n public setup(params: {\n media: HTMLAudioElement | HTMLVideoElement;\n formats?: string[];\n autoplay?: boolean;\n listeners?: { [eventType: string]: (event: Event | Error) => void };\n }): MediaModule {\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 const { media, formats, listeners, autoplay } = params;\n\n if (!media) {\n return this;\n }\n\n this.media = media;\n\n for (const format of formats ?? []) {\n const audioMime = `audio/${format}`;\n const videoMime = `video/${format}`;\n\n const canAudio = this.media.canPlayType(audioMime);\n const canVideo = this.media.canPlayType(videoMime);\n\n if (/^(?:maybe|probably)/.test(canAudio) || /^(?:maybe|probably)/.test(canVideo)) {\n this.ext = format;\n break;\n }\n }\n\n if (listeners) {\n this.listeners = listeners;\n\n Object.keys(listeners).forEach((eventType: string) => {\n const listener = listeners[eventType];\n\n if (typeof listener === 'function') {\n listeners[eventType] = listener;\n }\n\n if (this.media) {\n this.media.addEventListener(eventType, listener, false);\n }\n });\n }\n\n this.media.addEventListener('loadstart', () => {\n if (this.media === null) {\n return;\n }\n\n // If the same `HTMLMediaElement`, recreate instance of `MediaElementAudioSourceNode` causes error\n if ((this.source === null) || (this.media !== media)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n }, false);\n\n this.media.addEventListener('ended', () => {\n if (this.media === null) {\n return;\n }\n\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n }, false);\n\n this.autoplay = autoplay ?? false;\n\n // in case of autoplay, `loadstart` event not fire\n if (this.autoplay && (this.source === null)) {\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 ?? 0);\n })\n .catch((error: Error) => {\n if (this.listeners.error) {\n this.listeners.error(error);\n }\n });\n }\n\n return this;\n }\n\n /**\n * This method prepares for playing media anytime after loading media resource.\n * @param {string} src This argument is Object URL or file name for media resource.\n * @param {string} mimeType This argument is required in case of audio streaming.\n * @return {MediaModule} Return value is for method chain.\n */\n public ready(src: string, mimeType?: string): MediaModule {\n if (this.media === null) {\n return this;\n }\n\n if (this.mediaSource && (this.mediaSource.readyState === 'open')) {\n this.mediaSource.endOfStream();\n window.URL.revokeObjectURL(this.media.src);\n\n this.mediaSource.removeEventListener('sourceopen', this.onSourceOpen, false);\n this.mediaSource.removeEventListener('sourceended', this.onSourceEnded, false);\n this.mediaSource.removeEventListener('sourceclose', this.onSourceClose, false);\n\n if (this.sourceBuffer) {\n this.sourceBuffer.removeEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sourceBuffer.removeEventListener('error', this.onSourceBufferError, false);\n }\n }\n\n if (mimeType) {\n // Audio Streaming\n if (!MediaSource || !MediaSource.isTypeSupported(mimeType)) {\n return this;\n }\n\n this.media.removeAttribute('src');\n\n this.media.load();\n\n this.mediaSource = new MediaSource();\n this.media.src = window.URL.createObjectURL(this.mediaSource);\n this.mimeType = mimeType;\n this.file = src;\n\n this.mediaSource.addEventListener('sourceopen', this.onSourceOpen, false);\n this.mediaSource.addEventListener('sourceended', this.onSourceEnded, false);\n this.mediaSource.addEventListener('sourceclose', this.onSourceClose, false);\n } else if (src.startsWith('blob:') || (this.ext === '')) {\n // Object URL or file name\n this.media.src = src;\n } else {\n // file name (except extension)\n this.media.src = `${src}.${this.ext}`;\n }\n\n return this;\n }\n\n /**\n * This method starts media from designated time.\n * @param {number} position This argument is time that media is started at. The default value is `0`.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {MediaModule} Return value is for method chain.\n */\n public start(position?: number, errorCallback?: (error: Error) => void): MediaModule {\n if ((this.source === null) || (this.media === null)) {\n return this;\n }\n\n // MediaElementAudioSourceNode (Input) -> GainNode (Envelope Generator) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor);\n\n this.media.play()\n .then(() => {\n if (this.media === null) {\n return;\n }\n\n const startTime = this.context.currentTime;\n\n this.media.currentTime = position ?? 0;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(this.media.duration)) {\n this.envelopegenerator.stop((startTime + ((this.media.duration - this.media.currentTime) / this.media.playbackRate)), true);\n }\n\n this.on(startTime);\n\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n })\n .catch(() => {\n this.stop(() => {\n if (this.media === null) {\n return;\n }\n\n if (this.autoplay) {\n this.media.muted = true;\n this.media.volume = 0;\n }\n\n this.start(position);\n }, errorCallback);\n });\n\n return this;\n }\n\n /**\n * This method stops media.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {MediaModule} Return value is for method chain.\n */\n public stop(successCallback?: () => void, errorCallback?: (error: Error) => void): MediaModule {\n if ((this.source === null) || (this.media === null)) {\n return this;\n }\n\n // ref: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted\n this.media.play()\n .then(() => {\n if (this.media === null) {\n return;\n }\n\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n if (successCallback) {\n successCallback();\n }\n })\n .catch((error: Error) => {\n if (errorCallback) {\n errorCallback(error);\n }\n });\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for media module.\n * This method is overloaded for type interface and type check.\n * @param {keyof MediaModuleParams|MediaModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {MediaModuleParams[keyof MediaModuleParams]|MediaModule} Return value is parameter for media module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'autoplay'): boolean;\n public param(params: 'playbackRate'): number;\n public param(params: 'currentTime'): number;\n public param(params: 'controls'): boolean;\n public param(params: 'loop'): boolean;\n public param(params: 'muted'): boolean;\n public param(params: 'duration'): boolean;\n public param(params: 'duration'): boolean;\n public param(params: MediaModuleParams): MediaModule;\n public param(params: keyof MediaModuleParams | MediaModuleParams): MediaModuleParams[keyof MediaModuleParams] | MediaModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'autoplay': {\n return this.autoplay;\n }\n\n case 'playbackRate': {\n return this.media?.playbackRate ?? 1;\n }\n\n case 'currentTime': {\n return this.media?.currentTime ?? 0;\n }\n\n case 'controls': {\n return this.media?.controls ?? false;\n }\n\n case 'loop': {\n return this.media?.loop ?? false;\n }\n\n case 'muted': {\n return this.media?.muted ?? false;\n }\n\n case 'duration': {\n // `duration` is infinite in case of audio streaming\n return Number.isNaN(this.media?.duration) ? 0 : (this.media?.duration ?? 0); // Getter only\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'playbackRate': {\n if (this.media && (typeof value === 'number')) {\n if (value > 0) {\n this.media.playbackRate = value;\n\n const startTime = this.context.currentTime;\n const currentTime = this.media.currentTime;\n const duration = this.media.duration;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / value)), true);\n }\n }\n }\n\n break;\n }\n\n case 'currentTime': {\n if (this.media && (typeof value === 'number')) {\n this.media.currentTime = value;\n\n const startTime = this.context.currentTime;\n const duration = this.media.duration;\n const playbackRate = this.media.playbackRate;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - value) / playbackRate)), true);\n }\n }\n\n break;\n }\n\n case 'controls': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.controls = value;\n }\n\n break;\n }\n\n case 'loop': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.loop = value;\n }\n\n break;\n }\n\n case 'muted': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.muted = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `MediaElementAudioSourceNode`.\n * @return {MediaElementAudioSourceNode|null}\n */\n public get(): MediaElementAudioSourceNode | null {\n return this.source;\n }\n\n /**\n * This method determines whether instance of `HTMLMediaElement` exists.\n * @return {boolean} If instance of `HTMLMediaElement` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public hasMedia(): boolean {\n return this.media !== null;\n }\n\n /**\n * This method determines whether instance of `MediaElementAudioSourceNode` exists.\n * @return {boolean} If instance of `MediaElementAudioSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public hasSource(): boolean {\n return this.source !== null;\n }\n\n /**\n * This method determines whether media is paused.\n * @return {boolean} If media is paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return (this.media === null) ? true : this.media.paused;\n }\n\n /**\n * This method gets or sets 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|MediaModule} Return value is fade-in time. Otherwise, return value is for method chain.\n */\n public fadeIn(time?: number): number | MediaModule {\n if (typeof time !== 'number') {\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.media?.currentTime ?? 0;\n const duration = this.media?.duration ?? 0;\n const playbackRate = this.media?.playbackRate ?? 1;\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 gets or sets 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|MediaModule} Return value is fade-out time. Otherwise, return value is for method chain.\n */\n public fadeOut(time?: number): number | MediaModule {\n if (typeof time !== 'number') {\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.media?.currentTime ?? 0;\n const duration = this.media?.duration ?? 0;\n const playbackRate = this.media?.playbackRate ?? 1;\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 requests Picture In Picture (PIP).\n * @return {Promise<PictureInPictureWindow>} Return value is `Promise`.\n */\n public requestPictureInPicture(): Promise<PictureInPictureWindow> {\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<void>} Return value is `Promise`.\n */\n public exitPictureInPicture(): Promise<void> {\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 /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets media module parameters as associative array.\n * @return {MediaModuleParams}\n * @override\n */\n public override params(): Required<MediaModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n autoplay : this.autoplay,\n playbackRate : this.media?.playbackRate ?? 1,\n controls : this.media?.controls ?? false,\n loop : this.media?.loop ?? false,\n muted : this.media?.muted ?? false,\n currentTime : this.media?.currentTime ?? 0,\n duration : Number.isNaN(this.media?.duration ?? 0) ? 0 : (this.media?.duration ?? 0),\n vocalcanceler: this.vocalcanceler.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceOpen(event: Event): void {\n if (this.mediaSource === null) {\n return;\n }\n\n this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeType);\n\n this.sourceBuffer.mode = 'sequence';\n\n this.sourceBuffer.addEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sourceBuffer.addEventListener('error', this.onSourceBufferError, false);\n\n const request = new Request(this.file);\n\n fetch(request)\n .then((response: Response) => {\n return response.arrayBuffer();\n })\n .then((data: ArrayBuffer) => {\n if (this.sourceBuffer) {\n this.sourceBuffer.appendBuffer(data);\n }\n })\n .catch((error: Error) => {\n if (this.listeners.error) {\n this.listeners.error(error);\n }\n })\n .finally(() => {\n if (this.listeners.sourceopen) {\n this.listeners.sourceopen(event);\n }\n });\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceEnded(event: Event): void {\n if (this.listeners.sourceended) {\n this.listeners.sourceended(event);\n }\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceClose(event: Event): void {\n if (this.listeners.sourceclose) {\n this.listeners.sourceclose(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceBufferUpdateEnd(event: Event): void {\n if (this.listeners.updateend) {\n this.listeners.updateend(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceBufferError(event: Event): void {\n if (this.listeners.error) {\n this.listeners.error(event);\n }\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class StreamModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { StreamModuleProcessor } from './StreamModuleProcessor';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface MediaStreamTrackAudioSourceNode extends AudioNode {\n}\n\nexport type StreamModuleParams = SoundModuleParams & {\n output?: boolean,\n track?: boolean\n};\n\nexport { StreamModuleProcessor };\n\n/**\n * This class is for processing sound data from WebRTC.\n */\nexport class StreamModule extends SoundModule {\n private sources: MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[] = [];\n private stream: MediaStream | null = null;\n private constraints: MediaStreamConstraints = {\n audio: true,\n video: false\n };\n\n // Parameters\n private output = true;\n private track = false;\n\n private paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, StreamModuleProcessor.name);\n }\n\n /**\n * This method sets up for using WebRTC.\n * @param {MediaStreamConstraints} constraints This argument is object based on `MediaStreamConstraints` dictionary.\n * @return {StreamModule} Return value is for method chain.\n */\n public setup(constraints?: MediaStreamConstraints): StreamModule {\n if (constraints) {\n this.constraints = { ...this.constraints, ...constraints };\n }\n\n return this;\n }\n\n /**\n * This method opens devices or sets instance of `MediaStream`.\n * @property {MediaStream} stream This argument is instance of `MediaStream`.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @return {Promise<MediaStream|Error>} Return value is `Promise` that `getUserMedia` returns.\n */\n public ready(params?: {\n stream?: MediaStream;\n successCallback?: (stream: MediaStream) => void;\n errorCallback?: (error: Error) => void;\n }): Promise<MediaStream|Error> {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia || !window.MediaStream) {\n return Promise.reject();\n }\n\n this.paused = false;\n\n if (params?.stream) {\n this.stream = params.stream;\n return Promise.resolve(this.stream);\n }\n\n return navigator.mediaDevices.getUserMedia(this.constraints)\n .then((stream: MediaStream) => {\n if (this.paused) {\n return stream;\n }\n\n this.stream = stream;\n\n if (params?.successCallback) {\n params.successCallback(stream);\n }\n\n return stream;\n })\n .catch((error: Error) => {\n if (params?.errorCallback) {\n params.errorCallback(error);\n }\n\n return error;\n });\n }\n\n /**\n * This method starts streaming.\n * @return {StreamModule} Return value is for method chain.\n */\n public start(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n if (this.track) {\n // Get instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (let i = 0, len = audioTracks.length; i < len; i++) {\n // @ts-expect-error `createMediaStreamTrackSource` is not defined\n this.sources[i] = this.context.createMediaStreamTrackSource(audioTracks[i]);\n\n // MediaStreamTrackAudioSourceNode (Input) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.sources[i].connect(this.processor);\n this.connect(this.processor);\n }\n } else {\n this.sources[0] = this.context.createMediaStreamSource(this.stream);\n\n // MediaStreamAudioSourceNode (Input) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.sources[0].connect(this.processor);\n this.connect(this.processor);\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 recorder\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.OUTPUT.connect(this.destination);\n }\n\n this.on(this.context.currentTime);\n\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n return this;\n }\n\n /**\n * This method stops streaming.\n * @return {StreamModule} Return value is for method chain.\n */\n public stop(): StreamModule {\n this.sources.length = 0;\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n this.paused = true;\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for stream module.\n * This method is overloaded for type interface and type check.\n * @param {keyof StreamModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {StreamModuleParams[keyof StreamModuleParams]|StreamModule} Return value is parameter for stream module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'output'): boolean;\n public param(params: 'track'): boolean;\n public param(params: StreamModuleParams): StreamModule;\n public param(params: keyof StreamModuleParams | StreamModuleParams): StreamModuleParams[keyof StreamModuleParams] | StreamModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'output': {\n return this.output;\n }\n\n case 'track': {\n return this.track;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'output': {\n if (typeof value === 'boolean') {\n this.output = value;\n }\n\n break;\n }\n\n case 'track': {\n if (typeof value === 'boolean') {\n this.track = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode` or that array contains these.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode`.\n * @return {MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode}\n */\n public get(index: number): MediaStreamAudioSourceNode | MediaStreamTrackAudioSourceNode;\n public get(): MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[];\n public get(index?: number): MediaStreamAudioSourceNode | MediaStreamTrackAudioSourceNode | MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.sources.length)) {\n return this.sources[index];\n }\n\n return this.sources;\n }\n\n /**\n * This method gets instance of `MediaStream`.\n * @return {MediaStream|null}\n */\n public getStream(): MediaStream | null {\n return this.stream;\n }\n\n /**\n * This method gets current `MediaStreamConstraints`.\n * @return {MediaStreamConstraints}\n */\n public getConstraints(): MediaStreamConstraints {\n return this.constraints;\n }\n\n /**\n * This method changes `MediaStreamConstraints`.\n * @param {MediaStreamConstraints} constraints This argument is object based on `MediaStreamConstraints` dictionary.\n * @return {StreamModule} Return value is for method chain.\n */\n public setConstraints(constraints: MediaStreamConstraints): StreamModule {\n this.constraints = constraints;\n return this;\n }\n\n /**\n * This method stops microphone and camera by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clear(): StreamModule {\n this.stop();\n\n this.clearAudioDevices();\n this.clearVideoDevices();\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clearAudioDevices(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get 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 camera by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clearVideoDevices(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get 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 instance of `MediaDeviceInfo`.\n * @return {Promise<MediaDeviceInfo[]|void>} Return value is `Promise` that has array contains instance of `MediaDeviceInfo`.\n */\n public devices(): Promise<MediaDeviceInfo[]|void> {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return Promise.reject();\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 public streaming(): boolean {\n return !this.paused;\n }\n\n /**\n * This method enables to designate input device.\n * @param {string} deviceId This argument is string as input device ID.\n * @return {StreamModule} Return value is for method chain.\n */\n public setInputDeviceId(deviceId: string): StreamModule {\n const audioConstraints = this.constraints.audio ?? {};\n\n if (typeof audioConstraints === 'boolean') {\n this.constraints = {\n ...this.constraints,\n audio: {\n deviceId\n }\n };\n } else {\n this.constraints = {\n ...this.constraints,\n audio: {\n ...audioConstraints,\n deviceId\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets stream module parameters as associative array.\n * @return {StreamModuleParams}\n * @override\n */\n public override params(): Required<StreamModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n output : this.output,\n track : this.track,\n noisegate : this.noisegate.params(),\n noisesuppressor: this.noisesuppressor.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\n\n/**\n * This subclass is for using `AudioWorkletNode` as sound source.\n */\nexport class ProcessorModule extends SoundModule {\n private processorName = '';\n private options: AudioWorkletNodeOptions = {};\n private moduleURL = '';\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.envelopegenerator.setGenerator(0);\n }\n\n /**\n * This method sets registered processor name and options for `AudioWorkletNode` constructor.\n * @param {string} processorName This argument is name of `AudioWorkletProcessor`.\n * @param {AudioWorkletNodeOptions} options This argument is object based on `AudioWorkletNodeOptions` dictionary.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public setup(processorName: string, options?: AudioWorkletNodeOptions): ProcessorModule {\n this.processorName = processorName;\n this.options = options ?? {};\n\n return this;\n }\n\n /**\n * This method adds module for AudioWorklet and creates instance of `AudioWorkletNode`.\n * @param {string} moduleURL This argument is string that contains URL of file (.js) with module to add.\n * @param {WorkletOptions} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise<void>} Return value is `Promise` that `addModule` returns.\n */\n public ready(moduleURL: string, options?: WorkletOptions): Promise<void> {\n this.moduleURL = moduleURL;\n\n return this.context.audioWorklet.addModule(this.moduleURL, options ?? { credentials: 'same-origin' })\n .then(() => {\n this.processor = new AudioWorkletNode(this.context, this.processorName, this.options);\n });\n }\n\n /**\n * This method starts sound by connecting to `AudioDestinationNode`.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public start(): ProcessorModule {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator === null) {\n return this;\n }\n\n const startTime = this.context.currentTime;\n\n if (!this.mixed) {\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(generator);\n }\n\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor, null);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n this.on(startTime);\n\n return this;\n }\n\n /**\n * This method stops sound by disconnecting to `AudioDestinationNode`.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public stop(): ProcessorModule {\n const stopTime = this.context.currentTime;\n\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n return this;\n }\n\n /**\n * This method sends message from `MessagePort` that `AudioWorkletNode` has.\n * @param {unknown} data This argument is sent as any data.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public postMessage(data: unknown): ProcessorModule {\n this.processor.port.postMessage(data);\n\n return this;\n }\n\n /**\n * This method sets event handler that is invoked on receiving message.\n * @param {function} callback This argument is invoked on receiving message.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public onMessage(callback: (event: MessageEvent) => void): ProcessorModule {\n this.processor.port.onmessage = callback;\n\n return this;\n }\n\n /**\n * This method sets event handler that is invoked on receiving message that cannot be deserialized.\n * @param {function} callback This argument is invoked on receiving message that cannot be deserialized.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public onMessageError(callback: (event: MessageEvent) => void): ProcessorModule {\n this.processor.port.onmessageerror = callback;\n\n return this;\n }\n\n /**\n * This method gets map based on `AudioParamMap`.\n * @return {AudioParamMap|null}\n */\n public map(): AudioParamMap {\n return this.processor.parameters;\n }\n\n /**\n * This method gets instance of `AudioWorkletNode`.\n * @return {AudioWorkletNode|null}\n */\n public get(): AudioWorkletNode {\n return this.processor;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override suspend() {\n super.suspend();\n\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (this.processor && generator) {\n generator.disconnect(0);\n this.processor.connect(generator);\n }\n\n return this;\n }\n\n /** @override */\n public override get INPUT(): GainNode | null {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n return generator;\n }\n\n return null;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for mixing sound source.\n */\nexport class MixerModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { MixerModuleProcessor } from './MixerModuleProcessor';\n\nexport { MixerModuleProcessor };\n\n/**\n * This class is for mixing sound sources (instance of `SoundModule` subclass).\n */\nexport class MixerModule extends SoundModule {\n private sources: SoundModule[] = [];\n private gainNodes: GainNode[] = [];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, MixerModuleProcessor.name);\n }\n\n /**\n * This method defines noop for the same API.\n */\n public setup(): MixerModule {\n // Noop\n return this;\n }\n\n /**\n * This method defines noop for the same API.\n */\n public ready(): MixerModule {\n // Noop\n return this;\n }\n\n /**\n * This method mixes sound sources (instance of `SoundModule` subclass).\n * @param {Array<SoundModule>} sources This argument is array that contains sound sources.\n * @param {Array<number>} gains This argument is array for each sound source volume.\n * @return {MixerModule} Return value is for method chain.\n */\n public start(sources: SoundModule[], gains?: number[]): MixerModule {\n this.sources = sources;\n\n for (let i = 0, len = this.sources.length; i < len; i++) {\n const source = this.sources[i];\n\n const stopTime = this.context.currentTime;\n\n source.off(stopTime);\n source.suspend();\n source.mix();\n\n if (source.INPUT) {\n this.gainNodes[i] = this.context.createGain();\n\n this.gainNodes[i].gain.value = gains ? gains[i] : 1;\n\n // Disconnect each connection to `AudioDestinationNode`\n source.disconnect();\n\n // AudioWorkletNode (each sound source) -> GainNode (each sound source volume) -> AudioWorkletNode (Mix sound sources)\n source.INPUT.connect(this.gainNodes[i]);\n this.gainNodes[i].connect(this.processor);\n }\n }\n\n // (... ->) AudioWorkletNode (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.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method demixes sound sources (instance of `SoundModule` subclass).\n * @return {MixerModule} Return value is for method chain.\n */\n public stop(): MixerModule {\n const stopTime = this.context.currentTime;\n\n this.off(stopTime);\n this.suspend();\n\n // Revert connection\n for (const source of this.sources) {\n source.demix();\n\n if (source.INPUT) {\n source.disconnect();\n source.connect(source.INPUT);\n }\n }\n\n for (const gainNode of this.gainNodes) {\n gainNode.disconnect(0);\n }\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for mixer module.\n * This method is overloaded for type interface and type check.\n * @param {keyof SoundModuleParams|SoundModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {SoundModuleParams[keyof SoundModuleParams]|MixerModule} Return value is parameter for mixer module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: SoundModuleParams): MixerModule;\n public param(params: keyof SoundModuleParams | SoundModuleParams): SoundModuleParams[keyof SoundModuleParams] | MixerModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets array that contains instance of `SoundModule` subclass.\n * @return {Array<SoundModule>}\n */\n public get(): SoundModule[] {\n return this.sources;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","/**\n * This class is for using Web MIDI API.\n */\nexport class MIDI {\n private midiAccess: MIDIAccess | null = null;\n private inputs: MIDIInput[] = [];\n private outputs: MIDIOutput[] = [];\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n }\n\n /**\n * This method invokes `requestMIDIAccess` and gets instance of `MIDIAccess`.\n * @property {MIDIOptions} options This argument is object based on `MIDIOptions` dictionary.\n * @property {function} successCallback This argument is invoked on `requestMIDIAccess` success.\n * @property {function} errorCallback This argument is invoked on `requestMIDIAccess` failure.\n * @return {Promise<MIDIAccess|void>} Return value is `Promise` that `requestMIDIAccess` method returns.\n */\n public setup(params: {\n options?: MIDIOptions;\n successCallback?(midiAccess: MIDIAccess, midiInputs: MIDIInput[], midiOutputs: MIDIOutput[]): void;\n errorCallback?(error: Error): void;\n }): Promise<MIDIAccess|void> {\n if (!navigator.requestMIDIAccess) {\n return Promise.reject();\n }\n\n const { options, successCallback, errorCallback } = params;\n\n return navigator.requestMIDIAccess(options)\n .then((midiAccess: MIDIAccess) => {\n this.midiAccess = midiAccess;\n\n midiAccess.inputs.forEach((input: MIDIInput) => {\n this.inputs.push(input);\n });\n\n midiAccess.outputs.forEach((output: MIDIOutput) => {\n this.outputs.push(output);\n });\n\n if (successCallback) {\n successCallback(this.midiAccess, this.inputs, this.outputs);\n }\n })\n .catch((error: Error) => {\n if (errorCallback) {\n errorCallback(error);\n }\n });\n }\n\n /**\n * This method gets instance of `MIDIAccess`.\n * @return {MIDIAccess|null}\n */\n public get(): MIDIAccess | null {\n return this.midiAccess;\n }\n}\n","/**\n * This function returns worker script as string by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {string} Return value is worker script as string.\n */\nexport function extractWorkerString(workerContainerString: string): string {\n return workerContainerString.replace(/^.+?\\{/s, '').replace(/\\};?$/s, '');\n}\n\n/**\n * This function returns worker script as `Blob` by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {Blob} Return value is worker script as `Blob`.\n */\nexport function createWorkerBlob(workerContainerString: string): Blob {\n return new Blob([extractWorkerString(workerContainerString)], { type: 'text/javascript' });\n}\n\n/**\n * This function returns worker script as Object URL by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {string} Return value is worker script as Object URL.\n */\nexport function createWorkerObjectURL(workerContainerString: string): string {\n return window.URL.createObjectURL(createWorkerBlob(workerContainerString));\n}\n","export type TokenType = 'TEMPO' | 'OCTAVE' | 'NOTE' | 'REST' | 'NUMBER' | 'TIE' | 'SPACE' | 'EOS' | 'UNKNOWN';\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<string|undefined, TokenType>([\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 class is entity for MML token.\n * This class has token type, token data and token value if token is number.\n */\nexport class Token {\n private _id: string;\n private _type: TokenType;\n private _token: string | undefined;\n private _value: number;\n\n /**\n * @param {string} id This argument is string that identifies MML token.\n * @param {TokenType} type This argument is one of 'TEMPO', 'OCTAVE', 'NOTE', 'REST', 'NUMBER', 'TIE', 'SPACE', 'EOS', 'UNKNOWN'.\n * @param {string|undefined} token This argument is string that constructs of token.\n */\n constructor(id: string, type: TokenType, token: string | undefined) {\n this._id = id;\n this._type = type;\n this._token = token;\n this._value = token ? Number(token) : -1;\n }\n\n /**\n * This method is getter for token type.\n */\n public get type(): TokenType {\n return this._type;\n }\n\n /**\n * This method is getter for token.\n */\n public get token(): string | undefined {\n return this._token;\n }\n\n /**\n * This method is getter for token value if token is number.\n */\n public get value(): number {\n return Number.isNaN(this._value) ? -1 : this._value;\n }\n\n /**\n * This method returns fields that `Token` has as JSON.\n */\n public toString(): string {\n return JSON.stringify({\n id : this._id,\n type : this._type,\n token: this._token,\n value: this._value\n });\n }\n}\n","import { TokenMap, Token } from './Token';\n\n/**\n * This class is for MML Tokenization.\n */\nexport class Tokenizer {\n public static id = 0;\n\n private tokens: string[] = [];\n private notes: string[] = [];\n private numbers: string[] = [];\n\n /**\n * @param {string} mml This argument is MML string.\n */\n constructor(mml: string) {\n // `reverse` for getting token by `pop`\n this.tokens = mml.trim().toUpperCase().split('').reverse();\n }\n\n /**\n * This method executes tokenization from MML.\n * @return {Token|null} Return value is instance of `Token`.\n */\n public get(): Token | null {\n let token = this.tokens.pop();\n let tokenType = TokenMap.get(token);\n\n Tokenizer.id++;\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while ((tokenType === 'SPACE')) {\n token = this.tokens.pop();\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n if (tokenType === 'EOS') {\n return new Token(Tokenizer.id.toString(10), 'EOS', token);\n }\n\n this.notes.length = 0;\n this.numbers.length = 0;\n\n switch (tokenType) {\n case 'TEMPO': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'TEMPO', token);\n }\n\n break;\n }\n\n case 'OCTAVE': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'OCTAVE', token);\n }\n\n break;\n }\n\n case 'NOTE': {\n if (token) {\n this.notes.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while (tokenType === 'NOTE') {\n this.notes.push(token);\n\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n break;\n }\n\n case 'REST': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'REST', token);\n }\n\n break;\n }\n\n case 'NUMBER': {\n if (token) {\n this.numbers.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while (tokenType === 'NUMBER') {\n this.numbers.push(token);\n\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n break;\n }\n\n case 'TIE': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'TIE', token);\n }\n\n break;\n }\n }\n\n return null;\n }\n}\n","import type { Token } from '../../src/MML/Token';\n\n/**\n * This class is entity for MML syntax tree.\n */\nexport class Tree {\n private static indent = 0;\n\n private _id: string;\n\n private _operator: Token;\n\n \n private _left: Tree | null;\n private _right: Tree | null;\n \n\n /**\n * @param {string} id This argument is string that identifies syntax tree node.\n * @param {Token} operator This argument is instance of `Token` as syntax tree node.\n * @param {Tree} left This argument is instance of `Tree` as left subtree.\n * @param {Tree} right This argument is instance of `Tree` as right subtree.\n */\n constructor(id: string, operator: Token, left: Tree | null, right: Tree | null) {\n this._id = id;\n this._operator = operator;\n this._left = left;\n this._right = right;\n }\n\n /**\n * This method concatenates subtree as right subtree.\n * @param {Tree} node This argument is instance of `Tree` as syntax tree node.\n */\n public concat(node: Tree): void {\n this._right = node; // Side Effect (Because of pointers that before and after trees have)\n }\n\n /**\n * This method is getter for operator.\n */\n public get operator(): Token {\n return this._operator;\n }\n\n /**\n * This method is getter for left subtree.\n */\n public get left(): Tree | null {\n return this._left;\n }\n\n /**\n * This method is getter for right subtree.\n */\n public get right(): Tree | null {\n return this._right;\n }\n\n /**\n * This method clears indent.\n */\n public clear(): void {\n Tree.indent = 0;\n }\n\n /**\n * This method represents tree status as string.\n */\n public toString(): string {\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.token} (id = ${this._id})`}\n${space} /\\\\\n${space}${this._left?.operator.token ?? ''}${((this._right !== null) && (this._right._operator.token !== undefined)) ? this.toString.call(this._right) : 'EOS'}\n`;\n }\n}\n\n/**\n * This class is error class for MML syntax error.\n */\nexport class MMLSyntaxError {\n private _token: Token;\n\n /**\n * @param {Token} token This argument is instance of `Token` that error occurs in.\n */\n constructor(token: Token) {\n this._token = token;\n }\n\n /**\n * This method is getter for instance of `Token`.\n */\n public get token(): Token {\n return this._token;\n }\n}\n","import { Tokenizer } from './Tokenizer';\nimport { Tree, MMLSyntaxError } from './Tree';\n\n/**\n * This class is Tree Construction (syntax tree) for MML (Music Macro Language).\n */\nexport class TreeConstructor {\n public static id = 0;\n\n private tokenizer: Tokenizer;\n private syntaxTree: Tree[] = [];\n\n /**\n * @param {Tokenizer} tokenizer This argument is instance of `Tokenizer`.\n */\n constructor(tokenizer: Tokenizer) {\n this.tokenizer = tokenizer;\n }\n\n /**\n * This method executes tree construction (parsing) from tokens.\n * @return {Array<Tree>|MMLSyntaxError} Return value is syntax tree.\n */\n public parse(): Tree[] | MMLSyntaxError {\n Tokenizer.id = 0;\n\n let token = this.tokenizer.get();\n let nextToken = this.tokenizer.get();\n\n while (true) {\n if (!token || !nextToken) {\n return this.syntaxTree;\n }\n\n TreeConstructor.id += 2;\n\n switch (token.type) {\n case 'TEMPO': {\n if (nextToken.type === 'NUMBER') {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), token, left, null);\n\n // /T\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(token);\n }\n\n case 'OCTAVE': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'NOTE': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'REST': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'NUMBER': {\n TreeConstructor.id -= 2;\n break;\n }\n\n case 'TIE': {\n if (this.syntaxTree.length > 0) {\n TreeConstructor.id--;\n\n const tree = new Tree((TreeConstructor.id - 0).toString(10), 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(token);\n }\n\n case 'EOS': {\n if (this.syntaxTree.length > 0) {\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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((TreeConstructor.id - 1).toString(10), token, null, null);\n\n this.syntaxTree.push(tree);\n }\n\n return this.syntaxTree;\n }\n }\n\n token = nextToken;\n nextToken = this.tokenizer.get();\n }\n }\n\n /**\n * This method releases memory that stack has.\n */\n public free(): void {\n this.syntaxTree.length = 0;\n }\n}\n","// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './WebAssemblyModules/FFT.wasm';\n\n// Constants for Music\n\n// 12 equal temperament\n//\n// Min -> 27.5 Hz (A), Max -> 4186 Hz (C)\n//\n// A * 1.0594630943592953 -> A# (half up)\nexport const EQUAL_TEMPERAMENT = 12 as const;\nexport const FREQUENCY_RATIO = 1.0594630943592953 as const; // 2 ** (1 / EQUAL_TEMPERAMENT)\nexport const MIN_A = 27.5 as const;\nexport const QUARTER_NOTE = 4 as const;\nexport const SHARP = '#' as const;\nexport const HALF_UP = '+' as const;\nexport const HALF_DOWN = '-' as const;\nexport const DOT = '.' as const;\n\nexport type PitchChar = 'C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B' | 'R';\n\nexport type ConvertedTime = {\n minutes: number,\n seconds: number,\n milliseconds: number\n};\n\n/**\n * This predicate method determine whether is `PitchChar` type.\n * @param {string} pitchChar This argument is any string.\n * @return {boolean}\n */\nexport function isPitchChar(pitchChar: string): pitchChar is PitchChar {\n switch (pitchChar.toUpperCase()) {\n case 'C':\n case 'D':\n case 'E':\n case 'F':\n case 'G':\n case 'A':\n case 'B':\n case 'R': {\n return true;\n }\n\n default: {\n return false;\n }\n }\n}\n\n/**\n * This class (static) method computes index by octave and `PitchChar` string.\n * @param {number} octave This argument is octave.\n * @param {PitchChar} pitchChar This argument is `PitchChar` string.\n * @return {number} Return value is index that is computed by octave and pitch character.\n */\nexport function computeIndex(octave: number, pitchChar: PitchChar): number {\n let index = 0;\n\n switch (pitchChar) {\n case 'C': {\n index = 3;\n break;\n }\n\n case 'D': {\n index = 5;\n break;\n }\n\n case 'E': {\n index = 7;\n break;\n }\n\n case 'F': {\n index = 8;\n break;\n }\n\n case 'G': {\n index = 10;\n break;\n }\n\n case 'A': {\n index = 12;\n break;\n }\n\n case 'B': {\n index = 14;\n break;\n }\n\n case 'R': {\n return -1;\n }\n }\n\n const computedIndex = (EQUAL_TEMPERAMENT * (octave - 1)) + index;\n\n return (computedIndex >= 0) ? computedIndex : -1;\n}\n\n/**\n * This class (static) method computes frequency from index that corresponds to 12 equal temperament.\n * @param {number} index This argument is index that corresponds to 12 equal temperament.\n * For example, this value is between 0 and 88 in case of piano.\n * @return {number} Return value is frequency.\n */\nexport function computeFrequency(index: number): number {\n return (index >= 0) ? (MIN_A * (FREQUENCY_RATIO ** index)) : 0;\n}\n\n/**\n * This class (static) method computes frequency from `frequency` property and `detune` property (@see https://www.w3.org/TR/webaudio/#computedoscfrequency or https://www.w3.org/TR/webaudio/#computedfrequency).\n * @param {number} frequency This argument is `frequency` property as instance of `AudioParam`.\n * @param {number} detune This argument is `detune` property as instance of `AudioParam`.\n * @return {number} Return value is computed frequency (Hz).\n */\nexport function computeHz(frequency: number, detune: number): number {\n if (frequency <= 0) {\n return 0;\n }\n\n return frequency * (2 ** (detune/ 1200));\n}\n\n/**\n * This class (static) method computes playback rate from `playbackRate` property and `detune` property (@see https://www.w3.org/TR/webaudio/#computedplaybackrate).\n * @param {number} playbackRate This argument is `playbackRate` property as instance of `AudioParam`.\n * @param {number} detune This argument is `detune` property as instance of `AudioParam`.\n * @return {number} Return value is computed playback rate.\n */\nexport function computePlaybackRate(playbackRate: number, detune: number): number {\n if (playbackRate <= 0) {\n return 1;\n }\n\n return playbackRate * (2 ** (detune / 1200));\n}\n\nexport interface FileEvent extends Event {\n target: HTMLInputElement & EventTarget;\n}\n\n// Utility types and functions\n\nexport type FileReaderType = 'arraybuffer' | 'dataURL' | 'text' | 'json';\nexport type FileReaderErrorText = 'NOT_FOUND_ERR' | 'SECURITY_ERR' | 'ABORT_ERR' | 'NOT_READABLE_ERR' | 'ERR' | '';\n\nexport type WindowFunction = 'rect' | 'hanning' | 'hamming' | 'blackman';\n\n/**\n * This class (static) method applies window function\n * @param {number} size This argument is size of window function.\n * @param {WindowFunction} type This argument is type of window function. The default value is 'rect' (rectangular window).\n * @return {Float32Array} Return value is instance of `Float32Array` as window function.\n */\nexport function windowFunction(size: number, type: WindowFunction = 'rect'): Float32Array {\n if (size <= 0) {\n return new Float32Array([]);\n }\n\n const w = new Float32Array(size);\n\n switch (type) {\n case 'rect': {\n for (let n = 0; n < size; n++) {\n w[n] = 1.0;\n }\n\n break;\n }\n\n case 'hanning': {\n for (let n = 0; n < size; n++) {\n w[n] = 0.5 - (0.5 * Math.cos((2.0 * Math.PI * n) / (size - 1)));\n }\n\n break;\n }\n\n case 'hamming': {\n for (let n = 0; n < size; n++) {\n w[n] = 0.54 - (0.46 * Math.cos((2.0 * Math.PI * n) / (size - 1)));\n }\n\n break;\n }\n\n case 'blackman': {\n const alpha = 0.16;\n\n const a0 = (1.0 - alpha) / 2.0;\n const a1 = 1 / 2;\n const a2 = alpha / 2.0;\n\n for (let n = 0; n < size; n++) {\n w[n] = a0 - (a1 * Math.cos((2.0 * Math.PI * n) / (size - 1))) + (a2 * Math.cos((4.0 * Math.PI * n) / (size - 1)));;\n }\n\n break;\n }\n }\n\n return w;\n}\n\nexport interface FFTWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n FFT: (size: number) => void;\n IFFT: (size: number) => void;\n alloc_memory_reals: (size: number) => number;\n alloc_memory_imags: (size: number) => number;\n};\n\nlet instance: WebAssembly.Instance | null = null;\n\nWebAssembly.instantiateStreaming(fetch(wasm))\n .then((source: WebAssembly.WebAssemblyInstantiatedSource) => {\n instance = source.instance;\n })\n .catch((error: Error) => {\n return error;\n });\n\n/**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\nexport function fft(reals: Float32Array, imags: Float32Array, size: number): void {\n if (instance === null) {\n return;\n }\n\n // HACK:\n const wasm = instance.exports as FFTWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetReal = wasm.alloc_memory_reals(size);\n const offsetImag = wasm.alloc_memory_imags(size);\n\n const realsLinearMemory = new Float32Array(linearMemory, offsetReal, size);\n const imagsLinearMemory = new Float32Array(linearMemory, offsetImag, size);\n\n realsLinearMemory.set(reals);\n imagsLinearMemory.set(imags);\n\n wasm.FFT(size);\n\n reals.set(realsLinearMemory);\n imags.set(imagsLinearMemory);\n}\n\n/**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\nexport function ifft(reals: Float32Array, imags: Float32Array, size: number): void {\n if (instance === null) {\n return;\n }\n\n // HACK:\n const wasm = instance.exports as FFTWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetReal = wasm.alloc_memory_reals(size);\n const offsetImag = wasm.alloc_memory_imags(size);\n\n const realsLinearMemory = new Float32Array(linearMemory, offsetReal, size);\n const imagsLinearMemory = new Float32Array(linearMemory, offsetImag, size);\n\n realsLinearMemory.set(reals);\n imagsLinearMemory.set(imags);\n\n wasm.IFFT(size);\n\n reals.set(realsLinearMemory);\n imags.set(imagsLinearMemory);\n}\n\n/**\n * This class (static) method retrieves resource on web by Ajax.\n * @property {string} url This argument is URL for resource.\n * @property {XMLHttpRequestResponseType} type This argument is response type that is one of 'arraybuffer', 'blob', 'document', 'json', 'text'. The default value is 'arraybuffer'.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving data.\n */\nexport function ajax(params: {\n url: string;\n type?: XMLHttpRequestResponseType;\n timeout?: number;\n successCallback?(event: ProgressEvent, respsonse: ArrayBuffer | Blob | Document | string): void;\n errorCallback?(event: ProgressEvent, textStatus: 'error' | 'timeout'): void;\n progressCallback?(event: ProgressEvent): void;\n}): void {\n const { url, type, timeout, successCallback, errorCallback, progressCallback } = params;\n\n // for error\n const ERROR_AJAX = 'error';\n const ERROR_AJAX_TIMEOUT = 'timeout';\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (errorCallback) {\n errorCallback(event, ERROR_AJAX_TIMEOUT);\n }\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (errorCallback) {\n errorCallback(event, ERROR_AJAX);\n }\n };\n\n xhr.onload = (event: ProgressEvent) => {\n if (successCallback && (xhr.status === 200)) {\n successCallback(event, xhr.response);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = type ?? 'arraybuffer';\n xhr.send(null);\n}\n\n/**\n * This class (static) method calculates minutes, seconds and milliseconds from designated time (seconds).\n * @param {number} time This argument is time (seconds).\n * @return {ConvertedTime} Return value is converted time as associative array\n */\nexport function convertTime(time: number): ConvertedTime {\n if (time < 0) {\n return {\n minutes : -1,\n seconds : -1,\n milliseconds: -1\n };\n }\n\n const m = Math.trunc(time / 60);\n const s = Math.trunc(time % 60);\n const ms = time - Math.trunc(time);\n\n return {\n minutes : m,\n seconds : s,\n milliseconds: ms\n };\n}\n\n/**\n * This class (static) method decodes instance of `ArrayBuffer` to instance of `AudioBuffer`.\n * @param {AudioContext} context This argument is instance of `AudioContext` for `decodeAudioData` method.\n * @param {ArrayBuffer} arraybuffer This argument is decoded to instance of `AudioBuffer`.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {Promise<AudioBuffer>} Return value is instance of `Promise` that has instance of `AudioBuffer`.\n */\nexport function decode(\n context: AudioContext,\n arraybuffer: ArrayBuffer,\n successCallback?: (buffer: AudioBuffer) => void,\n errorCallback?: (error: Error) => void\n): Promise<AudioBuffer> {\n if (!successCallback) {\n successCallback = () => {};\n }\n\n if (!errorCallback) {\n errorCallback = () => {};\n }\n\n return context.decodeAudioData(arraybuffer, successCallback, errorCallback);\n}\n\n/**\n * This class (static) method queries browser permission.\n * @param {PermissionName} name This argument is string for `PermissionDescriptor`. For example, this argument is `'microphone'`.\n * @return {Promise<PermissionStatus>} Return value is instance of `Promise` that has instance of `PermissionStatus`.\n */\nexport function permission(name: PermissionName): Promise<PermissionStatus> {\n return navigator.permissions.query({ name });\n};\n\n/**\n * This class (static) method shows designated `Element` in full screen.\n * @param {Element} element This argument is instance of `Element` that is target of full screen.\n * @return {Promise} Return value is instance of `Promise`.\n */\nexport function requestFullscreen(element: Element): Promise<void> {\n return element.requestFullscreen();\n}\n\n/**\n * This class (static) method shows `Document` in original size from full screen.\n * @return {Promise} Return value is instance of `Promise`.\n */\nexport function exitFullscreen(): Promise<void> {\n return document.exitFullscreen();\n}\n\n/**\n * This class (static) method reads file.\n * @property {File} file This argument is instance of `File`.\n * @property {FileReaderType} type This argument is one of 'arraybuffer', 'dataURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n */\nexport function read(params: {\n file: File;\n type: FileReaderType;\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): void {\n const { file, type, successCallback, errorCallback, progressCallback } = params;\n\n const reader = new FileReader();\n\n reader.onprogress = (event: ProgressEvent) => {\n if (progressCallback) {\n progressCallback(event);\n }\n };\n\n reader.onerror = (event: ProgressEvent) => {\n if (!errorCallback) {\n return;\n }\n\n let error: FileReaderErrorText;\n\n switch (reader.error?.code) {\n case reader.error?.NOT_FOUND_ERR: {\n error = 'NOT_FOUND_ERR';\n break;\n }\n\n case reader.error?.SECURITY_ERR: {\n error = 'SECURITY_ERR';\n break;\n }\n\n case reader.error?.ABORT_ERR: {\n error = 'ABORT_ERR';\n break;\n }\n\n case reader.error?.NOT_SUPPORTED_ERR: {\n error = 'NOT_READABLE_ERR';\n break;\n }\n\n default: {\n error = 'ERR';\n break;\n }\n }\n\n errorCallback(event, error);\n };\n\n reader.onload = (event: ProgressEvent) => {\n if (!successCallback) {\n return;\n }\n\n let result = reader.result;\n\n // Escape `<script>` if `FileReaderType` is either `text` or `json`\n switch (type) {\n case 'text': {\n if (typeof result === 'string') {\n result = result.replace(/<(\\/?script.*?)>/gi, '<$1>');\n }\n\n break;\n }\n\n case 'json': {\n if (typeof result === 'string') {\n result = JSON.parse(result.replace(/<(\\/?script.*?)>/gi, '<$1>'));\n }\n\n break;\n }\n }\n\n successCallback(event, result);\n };\n\n switch (type) {\n case 'arraybuffer': {\n reader.readAsArrayBuffer(file);\n break;\n }\n\n case 'dataURL': {\n reader.readAsDataURL(file);\n break;\n }\n\n case 'text':\n case 'json': {\n reader.readAsText(file, 'UTF-8');\n break;\n }\n }\n}\n\n/**\n * This class (static) method gets instance of `File` from `DataTransfer`.\n * @property {DragEvent} event This argument is instance of `DragEvent`.\n * @property {FileReaderType|string} type This argument is one of 'arraybuffer', 'dataURL', 'objectURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n * @return {string|File|null} Return value is Object URL or instance of `File` on success. Otherwise, it is `null`.\n */\nexport function drop(params: {\n event: DragEvent;\n type: FileReaderType | 'objectURL';\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): string | File | null {\n const { event, type, successCallback, errorCallback, progressCallback } = params;\n\n event.preventDefault();\n\n if (!event.dataTransfer?.items[0]) {\n return null;\n }\n\n const file = event.dataTransfer.items[0].getAsFile();\n\n if (file === null) {\n return null;\n }\n\n if (type === 'objectURL') {\n return window.URL.createObjectURL(file);\n }\n\n read({\n file,\n type,\n successCallback,\n errorCallback,\n progressCallback\n });\n\n return file;\n}\n\n/**\n * This class (static) method gets instance of `File`.\n * @property {Event} event This argument is instance of `Event` by `HTMLInputElement`.\n * @property {FileReaderType|string} type This argument is one of 'arraybuffer', 'dataURL', 'objectURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n * @return {string|File|null} Return value is Object URL or instance of `File` on success. Otherwise, it is `null`.\n */\nexport function file(params: {\n event: FileEvent;\n type: FileReaderType | 'objectURL';\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): string | File | null {\n const { event, type, successCallback, errorCallback, progressCallback } = params;\n\n // HACK:\n const file = event.target.files?.item(0) ?? null;\n\n if (file === null) {\n return null;\n }\n\n if (type === 'objectURL') {\n return window.URL.createObjectURL(file);\n }\n\n read({\n file,\n type,\n successCallback,\n errorCallback,\n progressCallback\n });\n\n return file;\n}\n\n/**\n * This class (static) method calculates frequency from index that corresponds to 12 equal temperament.\n * @param {Array<number>} indexes This argument is array that contains index that corresponds to 12 equal temperament.\n * For example, this value is between 0 and 88 in case of piano.\n * @return {Array<number>} Return value is array that contains frequency.\n */\nexport function toFrequencies(indexes: number[]): number[] {\n return indexes.map((index: number) => computeFrequency(index));\n}\n\n/**\n * This class (static) method creates text file.\n * @param {string} text This argument is string.\n * @param {boolean} asObjectURL This argument is `true` in case of getting text file as Object URL.\n * @return {string} Return value is text file as Data URL or Object URL.\n */\nexport function toTextFile(text: string, asObjectURL: boolean): string {\n if (asObjectURL) {\n const blob = new Blob([text], { type: 'text/plain' });\n\n return window.URL.createObjectURL(blob);\n }\n\n return `data:,${encodeURIComponent(text)}`;\n}\n","/**\n * This class is entity for sequence that has musical note.\n */\nexport class Sequence {\n private _id: string;\n private _note: string;\n private _indexes: number[];\n private _frequencies: number[];\n private _start: number;\n private _stop: number;\n private _duration: number;\n\n /**\n * @property {string} id This argument is string that identifies sequence.\n * @property {string} note This argument is string that corresponds to MML token.\n * @property {Array<number>} indexes This argument is array that contains index that corresponds to 12 equal temperament.\n * @property {Array<number>} frequencies This argument is array that contains frequency.\n * @property {number} start This argument is start time.\n * @property {number} stop This argument is stop time.\n * @property {number} duration This argument is duration.\n */\n constructor(params: {\n id: string;\n note: string;\n indexes: number[];\n frequencies: number[];\n start: number;\n stop: number;\n duration: number;\n }) {\n const { id, note, indexes, frequencies, start, stop, duration } = params;\n\n this._id = id;\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 case of tie.\n * @param {Sequence} sequence This argument is instance of `Sequence`.\n * @return {Sequence} Return value is new instance of `Sequence` that concatenates previous sequence.\n */\n public concat(sequence: Sequence): Sequence {\n return new Sequence({\n id : this._id,\n note : `${this._note}&${sequence.note}`,\n indexes : this._indexes,\n frequencies: this._frequencies,\n start : this._start,\n duration : this._duration + sequence.duration,\n stop : this._start + (this._duration + sequence.duration)\n });\n }\n\n /**\n * This method is getter for musical note as MML token.\n */\n public get note(): string {\n return this._note;\n }\n\n /**\n * This method is getter for array that contains index that corresponds to 12 equal temperament.\n */\n public get indexes(): number[] {\n return this._indexes;\n }\n\n /**\n * This method is getter for array that contains frequency.\n */\n public get frequencies(): number[] {\n return this._frequencies;\n }\n\n /**\n * This method is getter for start time.\n */\n public get start(): number {\n return this._start;\n }\n\n /**\n * This method is getter for stop time.\n */\n public get stop(): number {\n return this._stop;\n }\n\n /**\n * This method is getter for duration,\n */\n public get duration(): number {\n return this._duration;\n }\n\n /**\n * This method returns fields that `Sequence` has as JSON.\n */\n public toString(): string {\n return JSON.stringify({\n id : this._id,\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","import type { Tree } from './Tree';\n\nimport {\n EQUAL_TEMPERAMENT,\n QUARTER_NOTE,\n SHARP,\n HALF_UP,\n HALF_DOWN,\n DOT,\n isPitchChar,\n computeIndex,\n computeFrequency\n} from '../XSound';\nimport { Token } from './Token';\nimport { MMLSyntaxError } from './Tree';\nimport { TreeConstructor } from './TreeConstructor';\nimport { Sequence } from './Sequence';\n\n/**\n * This class converts syntax tree to array that contains musical note.\n */\nexport class Sequencer {\n private sequences: Sequence[] = [];\n private treeConstructor: TreeConstructor;\n private syntaxTree = '';\n\n private timeOf4note = 0;\n private octave = -1;\n private currentTime = 0;\n\n private errorCallback: (error: MMLSyntaxError) => void;\n\n /**\n * @param {TreeConstructor} treeConstructor This argument is instance of `TreeConstructor`.\n * @param {function} errorCallback This argument is invoked on error.\n */\n constructor(treeConstructor: TreeConstructor, errorCallback?: (error: MMLSyntaxError) => void) {\n this.treeConstructor = treeConstructor;\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\n } else {\n this.errorCallback = (error: MMLSyntaxError) => {\n throw error;\n };\n }\n }\n\n /**\n * This method calculates pitch and music time from Parse Tree.\n * @return {Array<Sequence>} Return value is array that contains instance of `Sequence`.\n * If error occurs, error handler is invoked. Return value is `undefined`.\n */\n public get(): Sequence[] | void {\n TreeConstructor.id = 0;\n\n const trees = this.treeConstructor.parse();\n\n if (!trees) {\n this.errorCallback(new MMLSyntaxError(new Token('1', 'UNKNOWN', '')));\n return;\n }\n\n if (trees instanceof MMLSyntaxError) {\n this.errorCallback(trees);\n return;\n }\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n\n let tree: Tree | null = trees[0];\n\n while (tree !== null) {\n if (!tree) {\n this.errorCallback(new MMLSyntaxError(new Token((this.sequences.length + 1).toString(10), 'UNKNOWN', '')));\n return;\n }\n\n if (tree instanceof MMLSyntaxError) {\n this.errorCallback(tree);\n return;\n }\n\n const operator = tree.operator;\n const type = operator.type;\n\n const left = tree.left;\n\n const value = left !== null ? left.operator.value : -1;\n\n switch (type) {\n case 'TEMPO': {\n if (value <= 0) {\n this.errorCallback(new MMLSyntaxError(operator));\n return;\n }\n\n this.timeOf4note = 60 / value;\n\n tree = tree.right;\n break;\n }\n\n case 'OCTAVE': {\n if (value < 0) {\n this.errorCallback(new MMLSyntaxError(operator));\n return;\n }\n\n this.octave = value;\n\n tree = tree.right;\n break;\n }\n\n case 'NOTE':\n case 'REST':\n case 'TIE' : {\n const r = this.push(type === 'TIE' ? tree.right : tree);\n\n if (r instanceof MMLSyntaxError) {\n this.errorCallback(r);\n return;\n }\n\n if (type === 'TIE') {\n this.concat();\n\n tree = tree.right?.right ?? null;\n } else {\n tree = tree.right;\n }\n\n break;\n }\n\n case 'EOS': {\n tree = tree.right;\n break;\n }\n }\n }\n\n this.syntaxTree = trees[0].toString();\n\n // Release Memory for improving MML performance\n this.treeConstructor.free();\n\n return this.sequences;\n }\n\n /**\n * This method returns string that represents MML syntax tree.\n * @return {string}\n */\n public getSyntaxTree(): string {\n return this.syntaxTree;\n }\n\n /**\n * This method constructs syntax tree.\n * @param {Tree|null} tree This argument is instance of `Tree` that is added to syntax tree.\n */\n private push(tree: Tree | null): Tree | void {\n if (tree === null) {\n return;\n }\n\n const left = tree.left;\n const right = tree.right;\n\n // Not leaf\n if ((left === null) || (right === null)) {\n return;\n }\n\n // Not leaf\n const leftToken = left.operator;\n const rightToken = right.operator;\n\n if ((leftToken === null) && (rightToken === null)) {\n // Traverse tree by recursive call\n this.push(left);\n this.push(right);\n return;\n }\n\n // Leaf\n const token = tree.operator.token;\n const value = leftToken.value;\n const digits = leftToken.token;\n\n const indexes: number[] = [];\n const frequencies: number[] = [];\n\n if (!token) {\n return;\n }\n\n for (let i = 0, len = token.length; i < len; i++) {\n const note = token.charAt(i);\n\n if (!isPitchChar(note)) {\n continue;\n }\n\n let index = computeIndex(this.octave, note);\n\n // Sharp or Flat (Half up or Half down) ?\n switch (token.charAt(i + 1)) {\n case HALF_UP:\n case SHARP : {\n index++;\n i++;\n break;\n }\n\n case HALF_DOWN: {\n index--;\n i++;\n break;\n }\n\n default: {\n // Normal (Natural)\n break;\n }\n }\n\n // in case of chord\n if (index >= indexes[0]) {\n index -= 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 = 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 if (digits) {\n const numberOf4note = QUARTER_NOTE / value;\n\n // Dotted note ?\n if (digits.includes(DOT)) {\n duration += 1.5 * (numberOf4note * this.timeOf4note);\n } else {\n duration += numberOf4note * this.timeOf4note;\n }\n }\n\n break;\n }\n\n case 6: {\n // Triplet of half note\n duration += (2 * this.timeOf4note) / 3;\n break;\n }\n\n case 12: {\n // Triplet of quarter note\n duration += this.timeOf4note / 3;\n break;\n }\n\n case 18: {\n // Nonuplet of half note\n duration += (2 * this.timeOf4note) / 9;\n break;\n }\n\n case 24: {\n // Triplet of 8th note\n duration += (0.5 * this.timeOf4note) / 3;\n break;\n }\n\n case 36: {\n // Nonuplet of quarter note\n duration += this.timeOf4note / 9;\n break;\n }\n\n case 48: {\n // Triplet of 16th note\n duration += (0.25 * this.timeOf4note) / 3;\n break;\n }\n\n case 72: {\n // Nonuplet of 8th note\n duration += (0.5 * this.timeOf4note) / 9;\n break;\n }\n\n case 96: {\n // Triplet of 32th note\n duration += (0.125 * this.timeOf4note) / 3;\n break;\n }\n\n case 144: {\n // Nonuplet of 16th note\n duration += (0.25 * this.timeOf4note) / 9;\n break;\n }\n\n case 192: {\n // Triplet of 64th note\n duration += (0.0625 * this.timeOf4note) / 3;\n break;\n }\n\n default: {\n this.errorCallback(new MMLSyntaxError(leftToken));\n return;\n }\n }\n\n const id = (this.sequences.length + 1).toString(10);\n const note = `${token}${digits}`;\n const start = this.currentTime;\n const stop = start + duration;\n\n this.sequences.push(new Sequence({ id, note, indexes, frequencies, start, stop, duration }));\n\n this.currentTime += duration;\n }\n\n /**\n * This method concatenates previous sequence and current sequence in case of tie.\n */\n private concat(): void {\n const current = this.sequences.pop();\n const previous = this.sequences.pop();\n\n if (previous && current) {\n this.sequences.push(previous.concat(current));\n }\n }\n}\n","export type MMLScheduleWorkerMessageEventType = 'schedule' | 'next' | 'stop';\n\nexport type MMLScheduleWorkerMessageEventData = {\n type: MMLScheduleWorkerMessageEventType,\n duration?: number\n};\n\nexport const schedule = () => {\n let timerId: number | null = null;\n\n self.onmessage = (event: MessageEvent<MMLScheduleWorkerMessageEventData>) => {\n switch (event.data.type) {\n case 'schedule': {\n if (typeof event.data.duration === 'number') {\n timerId = self.setTimeout(() => {\n const message: MMLScheduleWorkerMessageEventData = { type: 'next' };\n\n self.postMessage(message);\n }, (event.data.duration * 1000));\n }\n\n break;\n }\n\n case 'next': {\n break;\n }\n\n case 'stop': {\n if (timerId !== null) {\n self.clearTimeout(timerId);\n self.close();\n timerId = null;\n }\n\n break;\n }\n }\n };\n};\n","import type { MMLSyntaxError } from './Tree';\nimport type { Sequence } from './Sequence';\nimport type { MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './ScheduleWorker';\n\nimport { createWorkerObjectURL } from '../worker';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { NoiseModule } from '../NoiseModule';\nimport { Tokenizer } from './Tokenizer';\nimport { TreeConstructor } from './TreeConstructor';\nimport { Sequencer } from './Sequencer';\nimport { schedule } from './ScheduleWorker';\n\nexport type {\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData\n};\n\n/**\n * This class starts and stops each MML part.\n */\nexport class Part {\n private sequences: Sequence[] = [];\n private source: OscillatorModule | OneshotModule | NoiseModule;\n private mml: string;\n private syntaxTree: string;\n private previous: Sequence | null = null;\n private scheduleWorker: Worker | null = null;\n private currentIndex = 0;\n private currentPosition = 0;\n private offset = 0;\n private startCallback?(sequence: Sequence, offset?: number): void;\n private stopCallback?(sequence: Sequence, offset?: number): void;\n private endedCallback?(): void;\n private errorCallback?(error: MMLSyntaxError): void;\n\n /**\n * @property {OscillatorModule|OneshotModule|NoiseModule} source This argument selects sound source.\n * @property {string} mml This argument is MML string.\n * @property {number} offset This argument corrects index of one-shot audio.\n * @property {function} startCallback This argument is invoked on start musical note.\n * @property {function} stopCallback This argument is invoked on stop musical note.\n * @property {function} endedCallback This argument is invoked on ended.\n * @property {function} errorCallback This argument is invoked on syntax error.\n */\n constructor(params: {\n source: OscillatorModule | OneshotModule | NoiseModule;\n mml: string;\n offset?: number;\n startCallback?(sequence: Sequence, offset?: number): void;\n stopCallback?(sequence: Sequence, offset?: number): void;\n endedCallback?(): void;\n errorCallback?(error: MMLSyntaxError): void;\n }) {\n const {\n source,\n mml,\n offset,\n startCallback,\n stopCallback,\n endedCallback,\n errorCallback\n } = params;\n\n this.source = source;\n this.mml = mml;\n this.offset = offset ?? 0;\n\n if (startCallback) {\n this.startCallback = startCallback;\n }\n\n if (stopCallback) {\n this.stopCallback = stopCallback;\n }\n\n if (endedCallback) {\n this.endedCallback = endedCallback;\n }\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\n }\n\n const tokenizer = new Tokenizer(mml);\n const treeConstructor = new TreeConstructor(tokenizer);\n const sequencer = new Sequencer(treeConstructor, this.errorCallback);\n const sequences = sequencer.get();\n\n if (sequences) {\n this.sequences = sequences;\n }\n\n this.syntaxTree = sequencer.getSyntaxTree();\n\n const workerObjectURL = createWorkerObjectURL(schedule.toString());\n\n this.scheduleWorker = new Worker(workerObjectURL);\n\n window.URL.revokeObjectURL(workerObjectURL);\n }\n\n /**\n * This method starts MML. Moreover, this method schedules next sequence.\n * @param {boolean} highlight This argument is `true` in case of surrounding by `span.x-highlight` HTML.\n */\n public start(highlight: boolean): void {\n if (this.scheduleWorker === null) {\n return;\n }\n\n if (!this.sequences[this.currentIndex]) {\n this.stop();\n\n if (this.endedCallback) {\n this.endedCallback();\n }\n\n return;\n }\n\n const sequence = this.sequences[this.currentIndex++];\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\n if (this.startCallback) {\n this.startCallback(sequence);\n }\n } else if (this.source instanceof OneshotModule) {\n const indexes = sequence.indexes\n .filter((index: number) => index !== -1)\n .map((index: number) => index + this.offset);\n\n this.source.ready(0, sequence.duration).start(indexes);\n\n if (this.startCallback) {\n this.startCallback(sequence, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.start();\n\n if (this.startCallback) {\n this.startCallback(sequence);\n }\n }\n\n // ref: https://web.dev/audio-scheduling/\n const message: MMLScheduleWorkerMessageEventData = {\n type : 'schedule',\n duration: sequence.duration\n };\n\n this.scheduleWorker.postMessage(message);\n\n this.scheduleWorker.onmessage = (event: MessageEvent<MMLScheduleWorkerMessageEventData>) => {\n if (event.data.type !== 'next') {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n if (this.stopCallback) {\n this.stopCallback(sequence);\n }\n } else if (this.source instanceof OneshotModule) {\n if (this.stopCallback) {\n this.stopCallback(sequence, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(sequence);\n }\n }\n\n // for stopping MML\n this.previous = sequence;\n\n // Start next sequence\n this.start(highlight);\n };\n }\n\n /**\n * This method stops MML.\n */\n public stop(): void {\n if (this.scheduleWorker === null) {\n return;\n }\n\n if (this.previous === null) {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(this.previous);\n }\n } else if (this.source instanceof OneshotModule) {\n const indexes = this.previous.indexes\n .filter((index: number) => index !== -1)\n .map((index: number) => index + this.offset);\n\n this.source.stop(indexes);\n\n if (this.stopCallback) {\n this.stopCallback(this.previous, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(this.previous);\n }\n }\n\n const message: MMLScheduleWorkerMessageEventData = { type: 'stop' };\n\n this.scheduleWorker.postMessage(message);\n this.scheduleWorker.terminate();\n this.scheduleWorker = null;\n }\n\n /**\n * This method is getter for MML string.\n */\n public getMML(): string {\n return this.mml;\n }\n\n /**\n * This method is getter for array that contains sequence.\n */\n public getSequences(): Sequence[] {\n return this.sequences;\n }\n\n /**\n * This method is getter for string that represents MML syntax tree.\n */\n public getSyntaxTree(): string {\n return this.syntaxTree;\n }\n\n /**\n * This method determines whether sequence exists.\n * @return {boolean} If sequence exists, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.sequences.length > 0;\n }\n\n /**\n * This method determines whether MML part is paused.\n * @return {boolean} If MML part are paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return this.scheduleWorker === null;\n }\n\n /**\n * This method is getter for current sequence index.\n */\n public getCurrentIndex(): number {\n return this.currentIndex;\n }\n\n /**\n * This method is setter for current sequence index.\n * @param {number} index This argument is new sequence index.\n */\n public setCurrentIndex(index: number): void {\n if (index >= 0 && index < this.sequences.length) {\n this.currentIndex = index;\n }\n }\n}\n","import type { OscillatorModule } from '../OscillatorModule';\nimport type { OneshotModule } from '../OneshotModule';\nimport type { NoiseModule } from '../NoiseModule';\nimport type { TokenType, TokenMap, Token } from './Token';\nimport type { Tree, MMLSyntaxError } from './Tree';\nimport type { Sequence } from './Sequence';\nimport type { MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './Part';\n\nimport { Part } from './Part';\n\nexport type {\n Part,\n Sequence,\n MMLSyntaxError,\n Tree,\n TokenType,\n TokenMap,\n Token,\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData\n};\n\n/**\n * This class manages instance of `Part` for playing MML (Music Macro Language).\n */\nexport class MML {\n private parts: Part[] = [];\n\n private startCallback?(sequence: Sequence, offset?: number): void;\n private stopCallback?(sequence: Sequence, offset?: number): void;\n private endedCallback?(): void;\n private errorCallback?(error: MMLSyntaxError): void;\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n }\n\n /**\n * @property {function} startCallback This argument is invoked on starting MML.\n * @property {function} stopCallback This argument is invoked on stopping MML.\n * @property {function} endedCallback This argument is invoked on ending MML.\n * @property {function} errorCallback This argument is invoked on occurring MML syntax error.\n */\n public setup(callbacks?: {\n startCallback?(sequence: Sequence, offset?: number): void;\n stopCallback?(sequence: Sequence, offset?: number): void;\n endedCallback?(): void;\n errorCallback?(error: MMLSyntaxError): void;\n }): MML {\n if (callbacks?.startCallback) {\n this.startCallback = callbacks.startCallback;\n }\n\n if (callbacks?.stopCallback) {\n this.stopCallback = callbacks.stopCallback;\n }\n\n if (callbacks?.endedCallback) {\n this.endedCallback = callbacks.endedCallback;\n }\n\n if (callbacks?.errorCallback) {\n this.errorCallback = callbacks.errorCallback;\n }\n\n return this;\n }\n\n /**\n * This method parses MML string.\n * @property {OscillatorModule|OneshotModule|NoiseModule} source This argument selects sound source.\n * @property {Array<string>} mmls This argument is MML strings.\n * @property {number} offset This argument is in order to adjust index of one-shot audio.\n * @return {MML} Return value is for method chain.\n */\n public ready(params: {\n source: OscillatorModule | OneshotModule | NoiseModule;\n mmls: string[];\n offset?: number;\n }): MML {\n const { source, mmls, offset } = params;\n\n this.stop();\n this.clear();\n\n const startCallback = this.startCallback;\n const stopCallback = this.stopCallback;\n const endedCallback = this.endedCallback;\n const errorCallback = this.errorCallback;\n\n for (const mml of mmls) {\n this.parts.push(new Part({\n source,\n mml,\n offset,\n startCallback,\n stopCallback,\n endedCallback,\n errorCallback\n }));\n }\n\n return this;\n }\n\n /**\n * This method starts designated MML part. Moreover, this method schedules next sequence.\n * @param {number} partNumber This argument is part of MML.\n * @param {boolean} highlight This argument is `true` in case of surrounding by `span.x-highlight` HTML. The default value is `false`.\n * @return {MML} Return value is for method chain.\n */\n public start(partNumber: number, highlight?: boolean): MML {\n if ((partNumber >= 0) && (partNumber < this.parts.length)) {\n const part = this.parts[partNumber];\n\n part.start(highlight ?? false);\n }\n\n return this;\n }\n\n /**\n * This method stops the all of MML parts.\n * @return {MML} Return value is for method chain.\n */\n public stop(): MML {\n for (const part of this.parts) {\n part.stop();\n }\n\n return this;\n }\n\n /**\n * This method gets MML string.\n * @param {number} index This argument selects MML part.\n * @return {string}\n */\n public getMML(index: number): string {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getMML();\n }\n\n return '';\n }\n\n /**\n * This method gets array that contains MML string.\n * @return {Array<string>}\n */\n public getMMLs(): string[] {\n return this.parts.map((part: Part) => part.getMML());\n }\n\n /**\n * This method determines whether sequences exist.\n * @return {boolean} If sequences exist, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return (this.parts.length > 0) && this.parts.every((part: Part) => part.has());\n }\n\n /**\n * This method gets array that contains instance of `Sequence`.\n * @param {number} index This argument selects MML part.\n * @return {Array<Sequence>}\n */\n public getSequences(index: number): Sequence[] {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getSequences();\n }\n\n return [];\n }\n\n /**\n * This method gets array that contains instance of `Sequence` from the all of MML parts.\n * @return {Array<Array<Sequence>>}\n */\n public getAllSequences(): Sequence[][] {\n return this.parts.map((part: Part) => part.getSequences());\n }\n\n\n /**\n * This method gets string that represents MML syntax tree.\n * @param {number} index This argument selects MML part.\n * @return {string}\n */\n public getSyntaxTree(index: number): string {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getSyntaxTree();\n }\n\n return '';\n }\n\n /**\n * This method determines whether MMLs are paused.\n * @return {boolean} If MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return (this.parts.length === 0) || this.parts.every((part: Part) => part.paused());\n }\n\n /**\n * This method gets or sets current sequence index.\n * This method is overloaded for type interface and type check.\n * @param {number} partNumber This argument is part of MML.\n * @param {number} sequenceIndex This argument is sequence index.\n * If this argument is omitted, this method is getter for current sequence index.\n * @return {number|MML} Return value is for current sequence index. Otherwise, Return value is for method chain.\n */\n public currentIndex(partNumber: number): number;\n public currentIndex(partNumber: number, sequenceIndex: number): MML;\n public currentIndex(partNumber: number, sequenceIndex?: number): number | MML {\n if ((partNumber < 0) || (partNumber >= this.parts.length)) {\n return this;\n }\n\n if (sequenceIndex) {\n this.parts[partNumber].setCurrentIndex(sequenceIndex);\n return this;\n }\n\n return this.parts[partNumber].getCurrentIndex();\n }\n\n /**\n * This method clears instance of `Part`.\n * @return {MML} Return value is for method chain.\n */\n public clear(): MML {\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 /**\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 public toABC(mml: string, X?: number, T?: string, M?: string, L?: string, K?: string): string {\n // TODO: Refactor to use syntax tree\n\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 (!note) {\n return abc;\n }\n\n if (/T\\d+/i.test(note)) {\n const Q = Number(note.slice(1));\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 = Number(note.slice(1));\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.includes('&')) {\n splittedNotes = note.split('&');\n } else {\n splittedNotes = [note];\n }\n\n let chord = '';\n\n while (splittedNotes.length > 0) {\n const splittedNote = splittedNotes.shift();\n\n if (!splittedNote) {\n return abc;\n }\n\n const duration = Number(splittedNote.replace(/^.+?(\\d+)\\.*$/, '$1'));\n\n let n = '';\n let d = 0;\n\n switch (duration) {\n case 1: {\n n = splittedNote.replace('1', '256');\n break;\n }\n\n case 2: {\n n = splittedNote.replace('2', '128');\n break;\n }\n\n case 4: {\n n = splittedNote.replace('4', '64');\n break;\n }\n\n case 8: {\n n = splittedNote.replace('8', '32');\n break;\n }\n\n case 16: {\n n = splittedNote.replace('16', '16');\n break;\n }\n\n case 32: {\n n = splittedNote.replace('32', '8');\n break;\n }\n\n case 64: {\n n = splittedNote.replace('64', '4');\n break;\n }\n\n case 128: {\n n = splittedNote.replace('128', '2');\n break;\n }\n\n case 256: {\n n = splittedNote.replace('256', '1');\n break;\n }\n\n // Tuplet\n case 6: {\n n = `(3${splittedNote.replace('6', '128')}`;\n d = 128 / 3;\n break;\n }\n\n case 12: {\n n = `(3${splittedNote.replace('12', '64')}`;\n d = 64 / 3;\n break;\n }\n\n case 18: {\n n = `(9${splittedNote.replace('18', '128')}`;\n d = 128 / 9;\n break;\n }\n\n case 24: {\n n = `(3${splittedNote.replace('24', '32')}`;\n d = 32 / 3;\n break;\n }\n\n case 36: {\n n = `(9${splittedNote.replace('36', '64')}`;\n d = 64 / 9;\n break;\n }\n\n case 48: {\n n = `(3${splittedNote.replace('48', '16')}`;\n d = 16 / 3;\n break;\n }\n\n case 72: {\n n = `(9${splittedNote.replace('72', '32')}`;\n d = 32 / 9;\n break;\n }\n\n case 96: {\n n = `(3${splittedNote.replace('96', '8')}`;\n d = 8 / 3;\n break;\n }\n\n case 144: {\n n = `(9${splittedNote.replace('144', '16')}`;\n d = 16 / 9;\n break;\n }\n\n case 192: {\n n = `(3${splittedNote.replace('192', '4')}`;\n d = 4 / 3;\n break;\n }\n\n default: {\n return abc;\n }\n }\n\n if (n.includes('.')) {\n n = n.replace(/^(.+?)\\d+\\.+$/, `$1${1.5 * Number(n.replace(/^.+?(\\d+)\\.+$/, '$1'))}`);\n }\n\n if (n.includes('(')) {\n totalDuration += Number(n.replace(/^.+?(\\d+)\\.*$/i, '$1'));\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 }\n\n case 1: {\n o = ',,,';\n break;\n }\n\n case 2: {\n o = ',,';\n break;\n }\n\n case 3: {\n o = ',';\n break;\n }\n\n case 5: {\n o = '\\'';\n break;\n }\n\n case 6: {\n o = '\\'\\'';\n break;\n }\n\n case 7: {\n o = '\\'\\'\\'';\n break;\n }\n\n case 4 :\n default: {\n break;\n }\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","'use strict';\n\nimport type { SoundModule, SoundModuleParams, Module, ModuleName } from './SoundModule';\nimport type { OscillatorModuleParams, Glide, GlideParams, GlideType, Oscillator, OscillatorParams, OscillatorCustomType } from './OscillatorModule';\nimport type { OneshotModuleParams, OneshotSetting, OneshotSettings, OneshotErrorText } from './OneshotModule';\nimport type { NoiseModuleParams, NoiseType } from './NoiseModule';\nimport type { AudioModuleParams, AudioBufferSprite } from './AudioModule';\nimport type { MediaModuleParams } from './MediaModule';\nimport type { StreamModuleParams, MediaStreamTrackAudioSourceNode } from './StreamModule';\nimport type { Part, Sequence, MMLSyntaxError, Tree, TokenType, TokenMap, Token, MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './MML';\nimport type {\n AnalyserParams,\n Domain,\n DataType,\n FFTSize,\n Visualizer,\n VisualizerParams,\n Color,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n CurrentTimeStyles,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams\n} from './SoundModule/Analyser';\nimport type { RecorderParams, RecordType, QuantizationBit, WaveExportType, Frame, Channel, RecorderProcessorMessageEventData } from './SoundModule/Recorder';\nimport type { AutopannerParams } from './SoundModule/Effectors/Autopanner';\nimport type { BitCrusherParams } from './SoundModule/Effectors/BitCrusher';\nimport type { ChorusParams } from './SoundModule/Effectors/Chorus';\nimport type { CompressorParams } from './SoundModule/Effectors/Compressor';\nimport type { DelayParams } from './SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator, EnvelopeGeneratorParams } from './SoundModule/Effectors/EnvelopeGenerator';\nimport type { EqualizerParams } from './SoundModule/Effectors/Equalizer';\nimport type { FilterParams } from './SoundModule/Effectors/Filter';\nimport type { FlangerParams } from './SoundModule/Effectors/Flanger';\nimport type { FuzzParams } from './SoundModule/Effectors/Fuzz';\nimport type { ListenerParams } from './SoundModule/Effectors/Listener';\nimport type { NoiseGateParams } from './SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressorParams } from './SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDriveParams } from './SoundModule/Effectors/OverDrive';\nimport type { PannerParams, Position3D } from './SoundModule/Effectors/Panner';\nimport type { PhaserParams, PhaserNumberOfStages } from './SoundModule/Effectors/Phaser';\nimport type { PitchShifterParams } from './SoundModule/Effectors/PitchShifter';\nimport type { PreampParams, PreampType, PreampCurve } from './SoundModule/Effectors/Preamp';\nimport type {\n Marshall,\n MarshallParams,\n PreEqualizerParams as MarshallPreEqualizerParams,\n PostEqualizerParams as MarshallPostEqualizerParams\n} from './SoundModule/Effectors/Preamps/Marshall';\nimport type {\n MesaBoogie,\n MesaBoogieParams,\n PreEqualizerParams as MesaBoogiePreEqualizerParams,\n PostEqualizerParams as MesaBoogiePostEqualizerParams\n} from './SoundModule/Effectors/Preamps/MesaBoogie';\nimport type {\n Fender,\n FenderParams,\n PreEqualizerParams as FenderPreEqualizerParams,\n PostFilterParams as FenderPostFilterParams,\n SpeakerInches as FenderSpeakerInches\n} from './SoundModule/Effectors/Preamps/Fender';\nimport type { CabinetParams } from './SoundModule/Effectors/Preamps/Cabinet';\nimport type { ReverbParams, ReverbErrorText } from './SoundModule/Effectors/Reverb';\nimport type { RingmodulatorParams } from './SoundModule/Effectors/Ringmodulator';\nimport type { StereoParams } from './SoundModule/Effectors/Stereo';\nimport type { TremoloParams } from './SoundModule/Effectors/Tremolo';\nimport type { VocalCancelerParams, VocalCancelerAlgorithm } from './SoundModule/Effectors/VocalCanceler';\nimport type { WahParams } from './SoundModule/Effectors/Wah';\nimport type { PitchChar, ConvertedTime, FileEvent, FileReaderType, FileReaderErrorText, WindowFunction } from './XSound';\nimport type { FrozenArray, Inputs, Outputs, Parameters } from './worklet';\n\nimport './types';\nimport { SoundModuleProcessor } from './SoundModule';\nimport { OscillatorModule, OscillatorModuleProcessor } from './OscillatorModule';\nimport { OneshotModule, OneshotModuleProcessor } from './OneshotModule';\nimport { NoiseModule, NoiseModuleProcessor } from './NoiseModule';\nimport { AudioModule, AudioModuleProcessor } from './AudioModule';\nimport { MediaModule, MediaModuleProcessor } from './MediaModule';\nimport { StreamModule, StreamModuleProcessor } from './StreamModule';\nimport { ProcessorModule } from './ProcessorModule';\nimport { MixerModule, MixerModuleProcessor } from './MixerModule';\nimport { MIDI } from './MIDI';\nimport { MML } from './MML';\nimport { Analyser } from './SoundModule/Analyser';\nimport { Recorder, RecorderProcessor } from './SoundModule/Recorder';\nimport { Effector } from './SoundModule/Effectors/Effector';\nimport { Autopanner } from './SoundModule/Effectors/Autopanner';\nimport { BitCrusher } from './SoundModule/Effectors/BitCrusher';\nimport { Chorus } from './SoundModule/Effectors/Chorus';\nimport { Compressor } from './SoundModule/Effectors/Compressor';\nimport { Delay } from './SoundModule/Effectors/Delay';\nimport { Equalizer } from './SoundModule/Effectors/Equalizer';\nimport { Filter } from './SoundModule/Effectors/Filter';\nimport { Flanger } from './SoundModule/Effectors/Flanger';\nimport { Fuzz } from './SoundModule/Effectors/Fuzz';\nimport { Listener } from './SoundModule/Effectors/Listener';\nimport { NoiseGate } from './SoundModule/Effectors/NoiseGate';\nimport { NoiseSuppressor } from './SoundModule/Effectors/NoiseSuppressor';\nimport { OverDrive } from './SoundModule/Effectors/OverDrive';\nimport { Panner } from './SoundModule/Effectors/Panner';\nimport { Phaser } from './SoundModule/Effectors/Phaser';\nimport { PitchShifter } from './SoundModule/Effectors/PitchShifter';\nimport { Preamp } from './SoundModule/Effectors/Preamp';\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 { VocalCanceler } from './SoundModule/Effectors/VocalCanceler';\nimport { Wah } from './SoundModule/Effectors/Wah';\nimport { NoiseGateProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/NoiseGateProcessor';\nimport { NoiseSuppressorProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/NoiseSuppressorProcessor';\nimport { PitchShifterProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/PitchShifterProcessor';\nimport { VocalCancelerProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/VocalCancelerProcessor';\nimport {\n EQUAL_TEMPERAMENT,\n FREQUENCY_RATIO,\n MIN_A,\n QUARTER_NOTE,\n HALF_UP,\n HALF_DOWN,\n DOT,\n isPitchChar,\n computeIndex,\n computeFrequency,\n computeHz,\n computePlaybackRate,\n windowFunction,\n fft,\n ifft,\n ajax,\n convertTime,\n decode,\n permission,\n requestFullscreen,\n exitFullscreen,\n read,\n drop,\n file,\n toFrequencies,\n toTextFile\n} from './XSound';\nimport { addAudioWorklet } from './worklet';\n\nexport type Source = OscillatorModule | OneshotModule | NoiseModule | AudioModule | MediaModule | StreamModule | ProcessorModule | MixerModule | Analyser | MIDI | MML;\nexport type SourceName = 'oscillator' | 'oneshot' | 'noise' | 'audio' | 'media' | 'stream' | 'processor' | 'mixer' | 'analyser' | 'midi' | 'mml';\n\n// for legacy browsers\nwindow.AudioContext = window.AudioContext || window.webkitAudioContext;\nwindow.URL = window.URL || window.webkitURL;\n\nconst audiocontext = new AudioContext();\n\n// Memoize instance\nconst sources: { [sourceName: string]: Source | null } = {\n oscillator: null,\n oneshot : null,\n noise : null,\n audio : null,\n media : null,\n stream : null,\n processor : null,\n mixer : null,\n analyser : null,\n midi : null,\n mml : null\n};\n\nconst promise = Promise\n .all([\n addAudioWorklet(audiocontext, SoundModuleProcessor),\n addAudioWorklet(audiocontext, RecorderProcessor),\n addAudioWorklet(audiocontext, OscillatorModuleProcessor),\n addAudioWorklet(audiocontext, OneshotModuleProcessor),\n addAudioWorklet(audiocontext, NoiseModuleProcessor),\n addAudioWorklet(audiocontext, AudioModuleProcessor),\n addAudioWorklet(audiocontext, MediaModuleProcessor),\n addAudioWorklet(audiocontext, StreamModuleProcessor),\n addAudioWorklet(audiocontext, MixerModuleProcessor),\n addAudioWorklet(audiocontext, NoiseGateProcessor),\n addAudioWorklet(audiocontext, NoiseSuppressorProcessor),\n addAudioWorklet(audiocontext, PitchShifterProcessor),\n addAudioWorklet(audiocontext, VocalCancelerProcessor)\n ])\n .then(() => {\n sources.oscillator = new OscillatorModule(audiocontext);\n sources.oneshot = new OneshotModule(audiocontext);\n sources.noise = new NoiseModule(audiocontext);\n sources.audio = new AudioModule(audiocontext);\n sources.media = new MediaModule(audiocontext);\n sources.stream = new StreamModule(audiocontext);\n sources.processor = new ProcessorModule(audiocontext);\n sources.mixer = new MixerModule(audiocontext);\n sources.analyser = new Analyser(audiocontext);\n sources.midi = new MIDI();\n sources.mml = new MML();\n\n return sources;\n })\n .catch((error: Error) => {\n return error;\n });\n\n/**\n * This function gets instance of `Source`.\n * This functions is overloaded for type interface and type check.\n * @param {SourceName|string} sourceName This argument selects instance for sound source.\n * @return {Source|null}\n */\nfunction XSound(sourceName: 'oscillator'): OscillatorModule;\nfunction XSound(sourceName: 'oneshot'): OneshotModule;\nfunction XSound(sourceName: 'noise'): NoiseModule;\nfunction XSound(sourceName: 'audio'): AudioModule;\nfunction XSound(sourceName: 'media'): MediaModule;\nfunction XSound(sourceName: 'stream'): StreamModule;\nfunction XSound(sourceName: 'processor'): ProcessorModule;\nfunction XSound(sourceName: 'mixer'): MixerModule;\nfunction XSound(sourceName: 'analyser'): Analyser;\nfunction XSound(sourceName: 'midi'): MIDI;\nfunction XSound(sourceName: 'mml'): MML;\nfunction XSound(sourecName: string): Source | null {\n switch (sourecName) {\n case 'oscillator': {\n return sources.oscillator;\n }\n\n case 'oneshot': {\n return sources.oneshot;\n }\n\n case 'noise': {\n return sources.noise;\n }\n\n case 'audio': {\n return sources.audio;\n }\n\n case 'media': {\n return sources.media;\n }\n\n case 'stream': {\n return sources.stream;\n }\n\n case 'processor': {\n return sources.processor;\n }\n\n case 'mixer': {\n return sources.mixer;\n }\n\n case 'analyser': {\n return sources.analyser;\n }\n\n case 'midi': {\n return sources.midi;\n }\n\n case 'mml': {\n return sources.mml;\n }\n\n default: {\n return null;\n }\n }\n}\n\n/**\n * Class (Static) properties\n */\nXSound.SAMPLE_RATE = audiocontext.sampleRate;\nXSound.EQUAL_TEMPERAMENT = EQUAL_TEMPERAMENT;\nXSound.FREQUENCY_RATIO = FREQUENCY_RATIO;\nXSound.MIN_A = MIN_A;\nXSound.QUARTER_NOT = QUARTER_NOTE;\nXSound.HALF_UP = HALF_UP;\nXSound.HALF_DOWN = HALF_DOWN;\nXSound.DOT = DOT;\nXSound.isPitchChar = isPitchChar;\nXSound.computeIndex = computeIndex;\nXSound.computeHz = computeHz;\nXSound.computeFrequency = computeFrequency;\nXSound.computePlaybackRate = computePlaybackRate;\nXSound.windowFunction = windowFunction;\nXSound.fft = fft;\nXSound.ifft = ifft;\nXSound.ajax = ajax;\nXSound.convertTime = convertTime;\nXSound.decode = decode;\nXSound.permission = permission;\nXSound.requestFullscreen = requestFullscreen;\nXSound.exitFullscreen = exitFullscreen;\nXSound.read = read;\nXSound.drop = drop;\nXSound.file = file;\nXSound.toFrequencies = toFrequencies;\nXSound.toTextFile = toTextFile;\n\n// Export classes\nXSound.Analyser = Analyser;\nXSound.Recorder = Recorder;\n\nXSound.Effector = Effector;\nXSound.Autopanner = Autopanner;\nXSound.BitCrusher = BitCrusher;\nXSound.Chorus = Chorus;\nXSound.Compressor = Compressor;\nXSound.Delay = Delay;\nXSound.Equalizer = Equalizer;\nXSound.Filter = Filter;\nXSound.Flanger = Flanger;\nXSound.Fuzz = Fuzz;\nXSound.Listener = Listener;\nXSound.NoiseGate = NoiseGate;\nXSound.NoiseSuppressor = NoiseSuppressor;\nXSound.OverDrive = OverDrive;\nXSound.Panner = Panner;\nXSound.Phaser = Phaser;\nXSound.PitchShifter = PitchShifter;\nXSound.Preamp = Preamp;\nXSound.Reverb = Reverb;\nXSound.Ringmodulator = Ringmodulator;\nXSound.Stereo = Stereo;\nXSound.Tremolo = Tremolo;\nXSound.VocalCanceler = VocalCanceler;\nXSound.Wah = Wah;\n\n/**\n * This class (static) method changes `AudioContextState` to 'running'.\n * Initial state is 'suspended' by Autoplay Policy.\n * Therefore, this method must be invoked by user gestures.\n * @return {Promise<void>} Return value is `Promise`.\n */\nXSound.setup = (): Promise<void> => {\n if (audiocontext.state !== 'running') {\n return audiocontext.resume();\n }\n\n return Promise.resolve();\n};\n\n/**\n * This class (static) method returns `Promise` that waits instantiating `AudioWorkletProcessor`s.\n * @return {Promise<Source|null|Error>} Return value is `Promise`.\n */\nXSound.promise = (): Promise<typeof sources | Error> => {\n return promise;\n};\n\n/**\n * This class (static) method returns closure that gets cloned instance of `Source`.\n * @return {function}\n */\nXSound.clone = (): typeof ClonedXSound => {\n const clonedSources: { [sourceName: string]: Source | null } = {\n oscillator: null,\n oneshot : null,\n noise : null,\n audio : null,\n media : null,\n stream : null,\n processor : null,\n mixer : null,\n analyser : null,\n midi : null,\n mml : null\n };\n\n function ClonedXSound(sourceName: 'oscillator'): OscillatorModule;\n function ClonedXSound(sourceName: 'oneshot'): OneshotModule;\n function ClonedXSound(sourceName: 'noise'): NoiseModule;\n function ClonedXSound(sourceName: 'audio'): AudioModule;\n function ClonedXSound(sourceName: 'media'): MediaModule;\n function ClonedXSound(sourceName: 'stream'): StreamModule;\n function ClonedXSound(sourceName: 'processor'): ProcessorModule;\n function ClonedXSound(sourceName: 'mixer'): MixerModule;\n function ClonedXSound(sourceName: 'analyser'): Analyser;\n function ClonedXSound(sourceName: 'midi'): MIDI;\n function ClonedXSound(sourceName: 'mml'): MML;\n function ClonedXSound(sourecName: string): Source | null {\n switch (sourecName) {\n case 'oscillator': {\n return clonedSources.oscillator;\n }\n\n case 'oneshot': {\n return clonedSources.oneshot;\n }\n\n case 'noise': {\n return clonedSources.noise;\n }\n\n case 'audio': {\n return clonedSources.audio;\n }\n\n case 'media': {\n return clonedSources.media;\n }\n\n case 'stream': {\n return clonedSources.stream;\n }\n\n case 'processor': {\n return clonedSources.processor;\n }\n\n case 'mixer': {\n return clonedSources.mixer;\n }\n\n case 'analyser': {\n return clonedSources.analyser;\n }\n\n case 'midi': {\n return clonedSources.midi;\n }\n\n case 'mml': {\n return clonedSources.mml;\n }\n\n default: {\n return null;\n }\n }\n }\n\n ClonedXSound.free = (unusedSources: Source[]): void => {\n for (const unusedSource of unusedSources) {\n // Already deleted ?\n if (unusedSource === null) {\n continue;\n }\n\n Object.entries(clonedSources).forEach(([sourceName, clonedSource]: [string, Source | null]) => {\n if (unusedSource === clonedSource) {\n clonedSources[sourceName] = null;\n }\n });\n }\n };\n\n clonedSources.oscillator = new OscillatorModule(audiocontext);\n clonedSources.oneshot = new OneshotModule(audiocontext);\n clonedSources.noise = new NoiseModule(audiocontext);\n clonedSources.audio = new AudioModule(audiocontext);\n clonedSources.media = new MediaModule(audiocontext);\n clonedSources.stream = new StreamModule(audiocontext);\n clonedSources.processor = new ProcessorModule(audiocontext);\n clonedSources.mixer = new MixerModule(audiocontext);\n clonedSources.analyser = new Analyser(audiocontext);\n clonedSources.midi = new MIDI();\n clonedSources.mml = new MML();\n\n // Closure\n return ClonedXSound;\n};\n\n/**\n * This class (static) method releases memory of unused instances.\n * @param {Array<Source>} unusedSources This argument is array that contains unused instance of `Source`.\n */\nXSound.free = (unusedSources: Source[]): void => {\n for (const unusedSource of unusedSources) {\n // Already deleted ?\n if (unusedSource === null) {\n continue;\n }\n\n Object.entries(sources).forEach(([sourceName, memoizedSource]: [string, Source | null]) => {\n if (unusedSource === memoizedSource) {\n sources[sourceName] = null; // Release heap\n }\n });\n }\n};\n\n/**\n * This method deletes `XSound` function as global object.\n * @param {boolean} deep This argument selects whether deleting both of global objects.\n * If this value is `true`, both of global objects are deleted.\n * @return {XSound}\n */\nXSound.noConflict = (deep: boolean): typeof XSound => {\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 instance of `AudioContext`.\n * @return {AudioContext}\n */\nXSound.get = (): AudioContext => {\n return audiocontext;\n};\n\n/**\n * This class (static) method gets elapsed time from creating instance of `AudioContext`.\n * @return {number}\n */\nXSound.getCurrentTime = (): number => {\n return audiocontext.currentTime;\n};\n\nconst setup = (event: MouseEvent | TouchEvent): void => {\n event.stopImmediatePropagation();\n\n XSound\n .setup()\n .finally(() => {\n document.removeEventListener('mousedown', setup, false);\n document.removeEventListener('touchstart', setup, false);\n });\n};\n\ndocument.addEventListener('mousedown', setup, false);\ndocument.addEventListener('touchstart', setup, false);\n\nexport type {\n SoundModule,\n SoundModuleParams,\n SoundModuleProcessor,\n Module,\n ModuleName,\n OscillatorModule,\n OscillatorModuleParams,\n Glide,\n GlideParams,\n GlideType,\n Oscillator,\n OscillatorParams,\n OscillatorCustomType,\n OscillatorModuleProcessor,\n OneshotModule,\n OneshotModuleParams,\n OneshotSetting,\n OneshotSettings,\n OneshotErrorText,\n OneshotModuleProcessor,\n NoiseModule,\n NoiseModuleParams,\n NoiseType,\n NoiseModuleProcessor,\n AudioModule,\n AudioModuleParams,\n AudioBufferSprite,\n AudioModuleProcessor,\n MediaModule,\n MediaModuleParams,\n MediaModuleProcessor,\n StreamModule,\n StreamModuleParams,\n StreamModuleProcessor,\n MediaStreamTrackAudioSourceNode,\n ProcessorModule,\n MixerModule,\n MixerModuleProcessor,\n MIDI,\n MML,\n Part,\n Sequence,\n MMLSyntaxError,\n Tree,\n TokenType,\n TokenMap,\n Token,\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData,\n Analyser,\n AnalyserParams,\n Domain,\n DataType,\n FFTSize,\n Color,\n Visualizer,\n VisualizerParams,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n CurrentTimeStyles,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams,\n Recorder,\n RecorderParams,\n RecordType,\n QuantizationBit,\n WaveExportType,\n Frame,\n Channel,\n RecorderProcessor,\n RecorderProcessorMessageEventData,\n Effector,\n Autopanner,\n AutopannerParams,\n BitCrusher,\n BitCrusherParams,\n Chorus,\n ChorusParams,\n Compressor,\n CompressorParams,\n Delay,\n DelayParams,\n EnvelopeGenerator,\n EnvelopeGeneratorParams,\n Equalizer,\n EqualizerParams,\n Filter,\n FilterParams,\n Flanger,\n FlangerParams,\n Fuzz,\n FuzzParams,\n Listener,\n ListenerParams,\n NoiseGate,\n NoiseGateParams,\n NoiseGateProcessor,\n NoiseSuppressor,\n NoiseSuppressorParams,\n NoiseSuppressorProcessor,\n OverDrive,\n OverDriveParams,\n Panner,\n PannerParams,\n Position3D,\n Phaser,\n PhaserParams,\n PhaserNumberOfStages,\n PitchShifter,\n PitchShifterParams,\n PitchShifterProcessor,\n Preamp,\n PreampParams,\n PreampType,\n PreampCurve,\n Marshall,\n MarshallParams,\n MarshallPreEqualizerParams,\n MarshallPostEqualizerParams,\n MesaBoogie,\n MesaBoogieParams,\n MesaBoogiePreEqualizerParams,\n MesaBoogiePostEqualizerParams,\n Fender,\n FenderParams,\n FenderPreEqualizerParams,\n FenderPostFilterParams,\n FenderSpeakerInches,\n CabinetParams,\n Reverb,\n ReverbParams,\n ReverbErrorText,\n Ringmodulator,\n RingmodulatorParams,\n Stereo,\n StereoParams,\n Tremolo,\n TremoloParams,\n VocalCanceler,\n VocalCancelerParams,\n VocalCancelerAlgorithm,\n VocalCancelerProcessor,\n Wah,\n WahParams,\n PitchChar,\n ConvertedTime,\n FileEvent,\n FileReaderType,\n FileReaderErrorText,\n WindowFunction,\n FrozenArray,\n Inputs,\n Outputs,\n Parameters\n};\n\nexport { XSound, XSound as X };\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","AudioWorkletProcessor","port","MessagePort","constructor","_options","OverlapAddProcessor","static","frameSize","hopSize","numberOfOverlaps","inputBuffers","inputBuffersHead","inputBuffersToSend","outputBuffers","outputBuffersToRetrieve","options","super","processorOptions","this","allocateInputChannels","allocateOutputChannels","process","inputs","outputs","parameters","reallocateChannelsIfNeeded","readInputs","shiftInputBuffers","prepareInputBuffersToSend","processOverlapAdd","handleOutputBuffersToRetrieve","writeOutputs","shiftOutputBuffers","inputNumberOfChannels","length","outputNumberOfChannels","numberOfChannels","channelNumber","Float32Array","RENDER_QUANTUM_SIZE","subarray","fill","set","copyWithin","n","addAudioWorklet","context","processor","audioWorklet","addModule","encodeURIComponent","toString","name","createModule","SoundModuleProcessor","input","output","Visualizer","sampleRate","channel","analyser","isActive","graphics","canvas","svg","interval","styles","shape","gradients","offset","color","wave","grid","text","font","family","size","style","weight","width","cap","join","top","right","bottom","left","setup","element","HTMLCanvasElement","getContext","SVGSVGElement","connect","source","AudioNode","OUTPUT","start","data","minDecibels","maxDecibels","visualizeOnCanvas","visualizeBySVG","param","params","entries","clear","clearRect","height","innerHTML","create","mimeType","test","toDataURL","callback","type","quality","toBlob","replace","outerHTML","state","activate","deactivate","visualizeTimeDomainFloat32ArrayOnCanvas","innerWidth","innerHeight","middle","numberOfPlots","lineWidth","lineCap","lineJoin","waveColor","strokeStyle","beginPath","len","x","y","moveTo","lineTo","stroke","upside","gradient","createLinearGradient","addColorStop","fillStyle","fillRect","visualizeTimeDomainFloat32ArrayBySVG","linearGradientId","path","document","createElementNS","XMLNS","d","setAttribute","defs","createSVGLinearGradient","g","appendChild","rect","Math","abs","linearGradient","stop","createFontString","SVG_CURRENT_TIME_CLASS_NAME","SVG_SPRITE_CLASS_NAME","TimeOverview","currentImageData","currentSVGElement","currentDataSize","currentTime","sprite","plotInterval","textInterval","isDown","mode","offsetX","startTime","endTime","onMouseStart","bind","onMouseMove","onMouseUp","onTouchStart","onTouchMove","onTouchEnd","update","time","currentTimeColor","putImageData","baseX","trunc","querySelector","Number","getAttribute","spriteRect","parentNode","removeChild","prevRect","baseRect","classList","add","drag","visualizationNode","removeEventListener","handleEvent","window","addEventListener","_minDecibels","_maxDecibels","Uint8Array","gridColor","textColor","fontSize","parseInt","numberOfTexts","i","t","fillText","measureText","trim","getImageData","SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW","textContent","visualize","event","offsetLeft","parentElement","scrollLeft","getOffsetX","stopPropagation","preventDefault","MouseEvent","pageX","TouchEvent","touches","Time","timeText","ceil","amplitudeText","SVG_LINEAR_GRADIENT_ID_TIME","FFT","scale","logarithmicFrequencies","minFrequency","maxFrequency","ratio","log10Ratio","log10","Array","isArray","mindB","maxdB","range","actualSize","frequencyResolution","k","frequencyRatio","log10FrequencyRatio","isFinite","frequency","frequencyText","slice","forEach","amplitude","SVG_LINEAR_GRADIENT_ID_FFT","Spectrogram","duration","linearFrequencyTextInterval","timeTextInterval","timeOffset","numberOfSamples","renderSize","imagedata","colorFromNumber","numberToJetColor","rgba","max","min","setColorFromNumberFunction","func","frequencyBinCount","fftSize","samples","textAlign","toFixed","index","h","rectX","rectY","Analyser","analysers","splitter","timeOverviews","times","ffts","spectrograms","timeDomainAnimationIds","timeDomainTimerIds","frequencyDomainAnimationIds","frequencyDomainTimerIds","spectrogramAnimationIds","spectrogramTimerIds","createAnalyser","createChannelSplitter","createGain","smoothingTimeConstant","domain","buffer","undefined","disconnect","getChannelData","getByteTimeDomainData","getFloatTimeDomainData","requestAnimationFrame","setTimeout","getByteFrequencyData","getFloatFrequencyData","animationId","timerId","cancelAnimationFrame","clearTimeout","INPUT","Frame","id","dataBlocks","append","dataBlock","push","has","Channel","frames","channelGain","frame","frameNumber","gain","RecorderProcessor","message","postMessage","Recorder","channels","activeTrack","paused","AudioWorkletNode","onmessage","bufferSize","BUFFER_SIZE","inputLs","gainL","frameL","recordedLs","inputRs","gainR","frameR","recordedRs","numberOfTracks","ready","trackNumber","hasTrack","qbits","soundLs","soundRs","mixTrack","flatTrack","RATE","QBITS","CHANNELS","SAMPLES","SIZE","CHUNK_SIZE","RIFF_CHUNK_SIZE","BPS","DATA_SIZE","sounds","binary","round","Int16Array","base64","btoa","from","map","String","fromCodePoint","blob","Blob","URL","createObjectURL","hasChannel","some","every","flattenTrack","j","sum","numberOfElements","currentBlock","numberOfMaxBlocks","mixedValues","currentFrame","Effector","lfo","depth","rate","createOscillator","stopTime","releaseTime","toJSON","JSON","stringify","Autopanner","panner","createStereoPanner","pan","BitCrusher","shaper","inputShaper","outputShaper","inputLevel","outputLevel","bitsInput","bitsGain","bits","createWaveShaper","createConstantSource","curve","v","inputCurve","outputCurve","oversample","_startTime","_stopTime","_releaseTime","Chorus","delay","tone","dry","wet","feedback","depthRate","createDelay","createBiquadFilter","delayTime","Q","SQRT1_2","mix","Compressor","compressor","createDynamicsCompressor","threshold","knee","attack","release","Delay","MAX_DELAY_TIME","EnvelopeGenerator","generators","activeIndexes","activeCounter","decay","sustain","t0","t1","t2","t2Value","activeIndex","cancelScheduledValues","setValueAtTime","linearRampToValueAtTime","setTargetAtTime","useCurve","s","t3","t4","cancelAndHoldAtTime","setValueCurveAtTime","getGenerator","setGenerator","counter","MIN_GAIN","disconnected","generator","Equalizer","bass","treble","presence","Filter","filter","minFrequnecy","Flanger","Fuzz","positiveShaper","negativeShaper","positiveInputGain","negativeInputGain","positiveOutputGain","negativeOutputGain","outFilter","driveInput","level","drive","r","tanh","Listener","listener","positions","forwards","ups","z","setPosition","setOrientation","fx","fy","fz","ux","uy","uz","NoiseGateProcessor","instance","ArrayBuffer","WebAssembly","instantiate","then","catch","error","wasm","linearMemory","memory","offsetInput","alloc_memory_inputs","offsetOutput","noisegate","NoiseGate","fetch","async","response","arrayBuffer","NoiseSuppressorProcessor","noisesuppressor","NoiseSuppressor","OverDrive","inputGain","outputGain","d1","Panner","orientations","createPanner","refDistance","maxDistance","rolloffFactor","coneInnerAngle","coneOuterAngle","coneOuterGain","panningModel","distanceModel","positionX","positionY","positionZ","orientationX","orientationY","orientationZ","ox","oy","oz","Phaser","numberOfStages","filters","MAX_STAGES","stage","resonance","PitchShifterProcessor","timeCursor","pitch","speed","pitchshifter","shiftedOutput","PitchShifter","Cabinet","lowpass","notch","PreEqualizer","preGain","leadGain","highpass1","highpass2","highpass3","lead","PostEqualizer","highpass","Marshall","preEQ","postEQ","cabinet","createCurve","pre","post","preHighpass","postHighpass","shapers","usePostFilters","postFilters","peakingFilters","fc100","fc360","fc720","fc1600","fc4800","MesaBoogie","gainEdge","gainBody","gainBottom","iirLowpassFilters","iirHighpassFilters","mixer","coefficient1","PI","coefficient2","lowpassFeedforward1","lowpassFeedforward2","lowpassFeedback1","lowpassFeedback2","highpassFeedforward1","highpassFeedforward2","highpassFeedback1","highpassFeedback2","createIIRFilter","PostFilter","inch","tilt","speakerFilter","tiltFilter","Fender","postFilter","curves","c","peak","Preamp","preamp","Reverb","convolver","rirs","loadError","createConvolver","AudioBuffer","impulse","errorCallback","successCallback","decodeAudioData","preset","timeout","progressCallback","rir","load","xhr","XMLHttpRequest","ontimeout","onprogress","abort","onerror","onload","status","decodeSuccessCallback","decodeErrorCallback","open","responseType","send","Ringmodulator","Stereo","merger","createChannelMerger","Tremolo","VocalCancelerProcessor","algorithm","offsetInputL","alloc_memory_inputLs","offsetInputR","alloc_memory_inputRs","inputLinearMemoryL","inputLinearMemoryR","offsetOutputL","vocalcancelerL","offsetOutputR","vocalcancelerR","vocalcanceler_on_spectrum","BYTES_PER_ELEMENT","canceledInputLs","canceledInputRs","VocalCanceler","Wah","auto","envelopeFollower","sensitivity","cutoff","SoundModule","destination","modules","mastervolume","recorder","autopanner","bitcrusher","chorus","envelopegenerator","equalizer","flanger","fuzz","overdrive","phaser","reverb","ringmodulator","stereo","tremolo","vocalcanceler","wah","runningAnalyser","mixed","audioDestination","streamDestination","createMediaStreamDestination","sinkId","setSinkId","install","effector","extendedEffector","on","off","suspend","demix","edit","previousModules","init","OscillatorModuleProcessor","Glide","prevFrequency","nextFrequency","diff","oscillator","exponentialRampToValueAtTime","Oscillator","volume","octave","fine","custom","real","imag","detune","reals","imags","periodicWave","createPeriodicWave","setPeriodicWave","MAX_SIZE","OCTAVE","OscillatorModule","sources","glide","states","frequencies","moduleName","OneshotModuleProcessor","OneshotModule","resources","buffers","volumes","settings","transpose","url","indexes","bufferIndex","playbackRate","loop","loopStart","loopEnd","createBufferSource","reset","paramName","NoiseModuleProcessor","processing","_inputs","whitenoise","pinknoise","browniannoise","NoiseModule","AudioModuleProcessor","AudioModule","stopped","callbacks","decodeCallback","updateCallback","endedCallback","audiobuffer","end","computedPlaybackRate","computePlaybackRate","timeoverviewL","timeoverviewR","fadeIn","fadeOut","dataLs","dataRs","bufferLs","createBuffer","copyToChannel","bufferRs","sprites","keys","reduce","audioSprite","spriteName","MediaModuleProcessor","MediaModule","media","ext","autoplay","mediaSource","sourceBuffer","file","listeners","onSourceOpen","onSourceEnded","onSourceClose","onSourceBufferUpdateEnd","onSourceBufferError","formats","format","audioMime","videoMime","canAudio","canPlayType","canVideo","eventType","createMediaElementSource","pause","src","resume","readyState","endOfStream","revokeObjectURL","MediaSource","isTypeSupported","removeAttribute","startsWith","position","play","muted","controls","isNaN","hasMedia","hasSource","requestPictureInPicture","HTMLVideoElement","pictureInPictureEnabled","disablePictureInPicture","pictureInPictureElement","Promise","reject","exitPictureInPicture","addSourceBuffer","request","Request","appendBuffer","finally","sourceopen","sourceended","sourceclose","updateend","StreamModuleProcessor","StreamModule","stream","constraints","audio","video","track","navigator","mediaDevices","getUserMedia","MediaStream","resolve","audioTracks","getAudioTracks","createMediaStreamTrackSource","createMediaStreamSource","getStream","getConstraints","setConstraints","clearAudioDevices","clearVideoDevices","audioTrack","videoTracks","getVideoTracks","videoTrack","devices","enumerateDevices","streaming","setInputDeviceId","deviceId","audioConstraints","ProcessorModule","processorName","moduleURL","credentials","onMessage","onMessageError","onmessageerror","MixerModuleProcessor","MixerModule","gainNodes","gains","gainNode","MIDI","midiAccess","requestMIDIAccess","extractWorkerString","workerContainerString","createWorkerObjectURL","createWorkerBlob","TokenMap","Map","Token","_id","_type","_token","_value","token","Tokenizer","tokens","notes","numbers","mml","toUpperCase","split","reverse","pop","tokenType","Tree","_operator","_left","_right","operator","concat","node","indent","space","MMLSyntaxError","TreeConstructor","tokenizer","syntaxTree","parse","nextToken","tree","free","FREQUENCY_RATIO","isPitchChar","pitchChar","computeIndex","computedIndex","computeFrequency","read","reader","FileReader","code","NOT_FOUND_ERR","SECURITY_ERR","ABORT_ERR","NOT_SUPPORTED_ERR","result","readAsArrayBuffer","readAsDataURL","readAsText","instantiateStreaming","Sequence","_note","_indexes","_frequencies","_start","_stop","_duration","note","sequence","Sequencer","sequences","treeConstructor","timeOf4note","trees","getSyntaxTree","leftToken","rightToken","digits","charAt","numberOf4note","includes","current","previous","schedule","close","Part","scheduleWorker","currentIndex","currentPosition","startCallback","stopCallback","sequencer","workerObjectURL","Worker","highlight","prev","indexOf","terminate","getMML","getSequences","getCurrentIndex","setCurrentIndex","MML","parts","mmls","partNumber","part","getMMLs","getAllSequences","sequenceIndex","toABC","X","T","M","L","K","abc","match","totalDuration","shift","splittedNotes","chord","splittedNote","matches","tuplet","chordLength","restNote","AudioContext","webkitAudioContext","webkitURL","audiocontext","oneshot","noise","midi","promise","all","XSound","sourecName","SAMPLE_RATE","EQUAL_TEMPERAMENT","MIN_A","QUARTER_NOT","HALF_UP","HALF_DOWN","DOT","computeHz","windowFunction","w","cos","alpha","a0","a1","a2","fft","offsetReal","alloc_memory_reals","offsetImag","alloc_memory_imags","realsLinearMemory","imagsLinearMemory","ifft","IFFT","ajax","convertTime","minutes","seconds","milliseconds","decode","arraybuffer","permission","permissions","query","requestFullscreen","exitFullscreen","drop","dataTransfer","items","getAsFile","target","files","item","toFrequencies","toTextFile","asObjectURL","clone","clonedSources","ClonedXSound","unusedSources","unusedSource","sourceName","clonedSource","memoizedSource","noConflict","deep","getCurrentTime","stopImmediatePropagation"],"ignoreList":[],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"xsound.js","mappings":"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","sources":["webpack://xsound/webpack/universalModuleDefinition","webpack://xsound/webpack/bootstrap","webpack://xsound/webpack/runtime/define property getters","webpack://xsound/webpack/runtime/hasOwnProperty shorthand","webpack://xsound/webpack/runtime/make namespace object","webpack://xsound/./src/worklet.ts","webpack://xsound/./src/SoundModule/SoundModuleProcessor.ts","webpack://xsound/./src/SoundModule/Analyser/Visualizer.ts","webpack://xsound/./src/SoundModule/Analyser/TimeOverview.ts","webpack://xsound/./src/SoundModule/Analyser/Time.ts","webpack://xsound/./src/SoundModule/Analyser/FFT.ts","webpack://xsound/./src/SoundModule/Analyser/Spectrogram.ts","webpack://xsound/./src/SoundModule/Analyser/index.ts","webpack://xsound/./src/SoundModule/Recorder/Frame.ts","webpack://xsound/./src/SoundModule/Recorder/Channel.ts","webpack://xsound/./src/SoundModule/Recorder/RecorderProcessor.ts","webpack://xsound/./src/SoundModule/Recorder/index.ts","webpack://xsound/./src/SoundModule/Effectors/Effector.ts","webpack://xsound/./src/SoundModule/Effectors/Autopanner.ts","webpack://xsound/./src/SoundModule/Effectors/BitCrusher.ts","webpack://xsound/./src/SoundModule/Effectors/Chorus.ts","webpack://xsound/./src/SoundModule/Effectors/Compressor.ts","webpack://xsound/./src/SoundModule/Effectors/Delay.ts","webpack://xsound/./src/SoundModule/Effectors/EnvelopeGenerator.ts","webpack://xsound/./src/SoundModule/Effectors/Equalizer.ts","webpack://xsound/./src/SoundModule/Effectors/Filter.ts","webpack://xsound/./src/SoundModule/Effectors/Flanger.ts","webpack://xsound/./src/SoundModule/Effectors/Fuzz.ts","webpack://xsound/./src/SoundModule/Effectors/Listener.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/NoiseGateProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/NoiseGate.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/NoiseSuppressorProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/NoiseSuppressor.ts","webpack://xsound/./src/SoundModule/Effectors/OverDrive.ts","webpack://xsound/./src/SoundModule/Effectors/Panner.ts","webpack://xsound/./src/SoundModule/Effectors/Phaser.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/PitchShifterProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/PitchShifter.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Cabinet.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Marshall.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/MesaBoogie.ts","webpack://xsound/./src/SoundModule/Effectors/Preamps/Fender.ts","webpack://xsound/./src/SoundModule/Effectors/Preamp.ts","webpack://xsound/./src/SoundModule/Effectors/Reverb.ts","webpack://xsound/./src/SoundModule/Effectors/Ringmodulator.ts","webpack://xsound/./src/SoundModule/Effectors/Stereo.ts","webpack://xsound/./src/SoundModule/Effectors/Tremolo.ts","webpack://xsound/./src/SoundModule/Effectors/AudioWorkletProcessors/VocalCancelerProcessor.ts","webpack://xsound/./src/SoundModule/Effectors/VocalCanceler.ts","webpack://xsound/./src/SoundModule/Effectors/Wah.ts","webpack://xsound/./src/SoundModule/index.ts","webpack://xsound/./src/OscillatorModule/OscillatorModuleProcessor.ts","webpack://xsound/./src/OscillatorModule/Glide.ts","webpack://xsound/./src/OscillatorModule/Oscillator.ts","webpack://xsound/./src/OscillatorModule/index.ts","webpack://xsound/./src/OneshotModule/OneshotModuleProcessor.ts","webpack://xsound/./src/OneshotModule/index.ts","webpack://xsound/./src/NoiseModule/NoiseModuleProcessor.ts","webpack://xsound/./src/NoiseModule/index.ts","webpack://xsound/./src/AudioModule/AudioModuleProcessor.ts","webpack://xsound/./src/AudioModule/index.ts","webpack://xsound/./src/MediaModule/MediaModuleProcessor.ts","webpack://xsound/./src/MediaModule/index.ts","webpack://xsound/./src/StreamModule/StreamModuleProcessor.ts","webpack://xsound/./src/StreamModule/index.ts","webpack://xsound/./src/ProcessorModule/index.ts","webpack://xsound/./src/MixerModule/MixerModuleProcessor.ts","webpack://xsound/./src/MixerModule/index.ts","webpack://xsound/./src/MIDI/index.ts","webpack://xsound/./src/worker.ts","webpack://xsound/./src/MML/Token.ts","webpack://xsound/./src/MML/Tokenizer.ts","webpack://xsound/./src/MML/Tree.ts","webpack://xsound/./src/MML/TreeConstructor.ts","webpack://xsound/./src/XSound/index.ts","webpack://xsound/./src/MML/Sequence.ts","webpack://xsound/./src/MML/Sequencer.ts","webpack://xsound/./src/MML/ScheduleWorker.ts","webpack://xsound/./src/MML/Part.ts","webpack://xsound/./src/MML/index.ts","webpack://xsound/./src/main.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"xsound\"] = factory();\n\telse\n\t\troot[\"xsound\"] = factory();\n})(self, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// HACK:\nexport type FrozenArray<T> = Array<T>;\n\nexport type Inputs = FrozenArray<FrozenArray<Float32Array>>;\nexport type Outputs = FrozenArray<FrozenArray<Float32Array>>;\nexport type Parameters = { [parameterName: string]: Float32Array };\n\n/**\n * This class enables to use inline AudioWorklet.\n */\nexport abstract class AudioWorkletProcessor {\n protected port = new MessagePort();\n protected abstract process(inputs: Inputs, outputs: Outputs, parameters: Parameters): boolean;\n\n // eslint-disable-next-line no-useless-constructor\n constructor(_options?: AudioWorkletNodeOptions) {\n }\n}\n\n/**\n * This class extends `AudioWorkletProcessor`.\n */\nexport abstract class OverlapAddProcessor extends AudioWorkletProcessor {\n private static readonly RENDER_QUANTUM_SIZE = 128;\n\n protected frameSize = 2048;\n protected hopSize = 128;\n protected numberOfOverlaps: number;\n\n private inputBuffers: Inputs = [[]];\n private inputBuffersHead: Inputs = [[]];\n private inputBuffersToSend: Inputs = [[]];\n\n private outputBuffers: Outputs = [[]];\n private outputBuffersToRetrieve: Outputs = [[]];\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n if (options.processorOptions) {\n this.frameSize = options.processorOptions.frameSize ?? 2048;\n }\n\n this.numberOfOverlaps = this.frameSize / this.hopSize;\n\n this.allocateInputChannels(1);\n this.allocateOutputChannels(1);\n }\n\n protected abstract processOverlapAdd(inputs: Inputs, outputs: Outputs, parameters: Parameters): void;\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs, parameters: Parameters): boolean {\n this.reallocateChannelsIfNeeded(inputs, outputs);\n\n this.readInputs(inputs);\n this.shiftInputBuffers();\n this.prepareInputBuffersToSend();\n this.processOverlapAdd(this.inputBuffersToSend, this.outputBuffersToRetrieve, parameters);\n this.handleOutputBuffersToRetrieve();\n this.writeOutputs(outputs);\n this.shiftOutputBuffers();\n\n return true;\n }\n\n private reallocateChannelsIfNeeded(inputs: Inputs, outputs: Outputs): void {\n const inputNumberOfChannels = inputs[0].length;\n\n if (inputNumberOfChannels !== this.inputBuffers[0].length) {\n this.allocateInputChannels(inputNumberOfChannels);\n }\n\n const outputNumberOfChannels = outputs[0].length;\n\n if (outputNumberOfChannels !== this.outputBuffers[0].length) {\n this.allocateOutputChannels(outputNumberOfChannels);\n }\n }\n\n private allocateInputChannels(numberOfChannels: number): void {\n this.inputBuffers = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.inputBuffers[0][channelNumber] = new Float32Array(this.frameSize + OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n }\n\n this.inputBuffersHead = [[]];\n this.inputBuffersToSend = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.inputBuffersHead[0][channelNumber] = this.inputBuffers[0][channelNumber].subarray(0, this.frameSize);\n this.inputBuffersToSend[0][channelNumber] = new Float32Array(this.frameSize);\n }\n }\n\n private allocateOutputChannels(numberOfChannels: number): void {\n this.outputBuffers = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.outputBuffers[0][channelNumber] = new Float32Array(this.frameSize);\n }\n\n this.outputBuffersToRetrieve = [[]];\n\n for (let channelNumber = 0; channelNumber < numberOfChannels; channelNumber++) {\n this.outputBuffersToRetrieve[0][channelNumber] = new Float32Array(this.frameSize);\n }\n }\n\n private readInputs(inputs: Inputs): void {\n if (inputs[0].length && (inputs[0][0].length === 0)) {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].fill(0, this.frameSize);\n }\n\n return;\n }\n\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].set(inputs[0][channelNumber], this.frameSize);\n }\n }\n\n private writeOutputs(outputs: Outputs): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n outputs[0][channelNumber].set(this.outputBuffers[0][channelNumber].subarray(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE));\n }\n }\n\n private shiftInputBuffers(): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffers[0][channelNumber].copyWithin(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n }\n }\n\n private shiftOutputBuffers(): void {\n for (let channelNumber = 0; channelNumber < this.outputBuffers[0].length; channelNumber++) {\n this.outputBuffers[0][channelNumber].copyWithin(0, OverlapAddProcessor.RENDER_QUANTUM_SIZE);\n this.outputBuffers[0][channelNumber].subarray(this.frameSize - OverlapAddProcessor.RENDER_QUANTUM_SIZE).fill(0);\n }\n }\n\n private prepareInputBuffersToSend(): void {\n for (let channelNumber = 0; channelNumber < this.inputBuffers[0].length; channelNumber++) {\n this.inputBuffersToSend[0][channelNumber].set(this.inputBuffersHead[0][channelNumber]);\n }\n }\n\n private handleOutputBuffersToRetrieve(): void {\n for (let channelNumber = 0; channelNumber < this.outputBuffers[0].length; channelNumber++) {\n for (let n = 0; n < this.frameSize; n++) {\n this.outputBuffers[0][channelNumber][n] += this.outputBuffersToRetrieve[0][channelNumber][n] / this.numberOfOverlaps;\n }\n }\n }\n}\n\n/**\n * This function creates AudioWorklet script as Data URL.\n * @param {AudioWorkletGlobalScope.AudioWorkletProcessor} processor This argument is class that extends `AudioWorkletProcessor`.\n * @return {string} Return value is AudioWorklet script as Data URL.\n */\nexport function createModule(processor: new (options: AudioWorkletNodeOptions) => AudioWorkletProcessor): string {\n return `data:text/javascript,${encodeURIComponent(OverlapAddProcessor.toString())}; ${encodeURIComponent(processor.toString())}; registerProcessor('${processor.name}', ${processor.name})`;\n}\n\n/**\n * This function adds module as AudioWorklet.\n * @param {AudioContext} context This argument is instance of `AudioContext` for adding AudioWorklet module.\n * @param {AudioWorkletGlobalScope.AudioWorkletProcessor} processor This argument is class that extends `AudioWorkletProcessor`.\n * @param {WorkletOptions} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise<void>} Return value is `Promise` that `addModule` returns.\n */\nexport function addAudioWorklet(context: AudioContext, processor: new (options: AudioWorkletNodeOptions) => AudioWorkletProcessor, options?: WorkletOptions): Promise<void> {\n return context.audioWorklet.addModule(createModule(processor), options);\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n * However, this processor is not used.\n */\nexport class SoundModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { Statable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { SoundModule } from '../../SoundModule';\n\nexport type Color = string;\n\nexport type GraphicsApi = 'canvas' | 'svg' | '';\n\nexport type Gradient = {\n offset: number,\n color: string\n};\n\nexport type Gradients = Gradient[];\n\nexport type Shape = 'line' | 'rect';\n\nexport type Font = {\n family?: string,\n size?: string,\n style?: string,\n weight?: string\n};\n\nexport type GraphicsStyles = {\n shape?: Shape,\n gradients?: Gradients,\n wave?: Color,\n grid?: Color,\n text?: Color,\n font?: Font,\n width?: number,\n cap?: CanvasLineCap,\n join?: CanvasLineJoin,\n top?: number,\n right?: number,\n bottom?: number,\n left?: number\n};\n\nexport type SpectrumScale = 'linear' | 'logarithmic';\n\nexport type VisualizerParams = {\n interval?: number,\n styles?: GraphicsStyles\n};\n\n/**\n * This private class is superclass for visualizer class (`TimeOverview`, `Time`, `FFT`).\n */\nexport abstract class Visualizer implements Statable {\n public static readonly XMLNS = 'http://www.w3.org/2000/svg' as const;\n public static readonly XLINK = 'http://www.w3.org/1999/xlink' as const;\n\n protected static SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW = 'svg-linear-gradient-time-overview';\n protected static SVG_LINEAR_GRADIENT_ID_TIME = 'svg-linear-gradient-time';\n protected static SVG_LINEAR_GRADIENT_ID_FFT = 'svg-linear-gradient-fft';\n\n protected sampleRate: number;\n protected channel: ChannelNumber;\n protected analyser: AnalyserNode | null = null;\n\n protected isActive = false;\n protected graphics: GraphicsApi = '';\n\n protected canvas: HTMLCanvasElement | null = null;\n protected context: CanvasRenderingContext2D | null = null;\n\n protected svg: SVGSVGElement | null = null;\n\n protected interval = 1000; // msec\n\n protected styles: GraphicsStyles = {\n shape : 'line',\n gradients: [\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 weight: '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 * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode | null = null) {\n this.sampleRate = sampleRate;\n this.channel = channel;\n this.analyser = analyser;\n }\n\n /**\n * This method sets up for using Canvas or SVG.\n * @param {HTMLCanvasElement|SVGSVGElement} element This argument is either `HTMLCanvasElement` or `SVGSVGElement`.\n * @return {Visualizer} Return value is for method chain.\n */\n public setup(element: HTMLCanvasElement | SVGSVGElement) {\n if (element instanceof HTMLCanvasElement) {\n this.graphics = 'canvas';\n this.canvas = element;\n this.context = this.canvas.getContext('2d');\n } else if (element instanceof SVGSVGElement) {\n this.graphics = 'svg';\n this.svg = element;\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method connects sound source to analyser node.\n * @param {SoundModule|AudioNode} source This argument is either `SoundModule` or `AudioNode`.\n * @return {Visualizer} Return value is for method chain.\n */\n public connect(source: SoundModule | AudioNode) {\n if (this.analyser === null) {\n return this;\n }\n\n if (source instanceof AudioNode) {\n source.connect(this.analyser);\n return;\n }\n\n source.OUTPUT.connect(this.analyser);\n\n return this;\n }\n\n /**\n * This method visualizes sound wave to Canvas or SVG. This method conceals difference of API for visualization.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\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} Return value is for method chain.\n */\n public start(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number) {\n switch (this.graphics) {\n case 'canvas': {\n this.visualizeOnCanvas(data, minDecibels, maxDecibels);\n break;\n }\n\n case 'svg': {\n this.visualizeBySVG(data, minDecibels, maxDecibels);\n break;\n }\n\n default: {\n break;\n }\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method gets or sets parameters for visualization.\n * This method is overloaded for type interface and type check.\n * @param {keyof VisualizerParams|VisualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {VisualizerParams[keyof VisualizerParams]} Return value is parameter for visualization if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'interval'): number;\n public param(params: 'styles'): GraphicsStyles;\n public param(params: VisualizerParams): void;\n public param(params: keyof VisualizerParams | VisualizerParams): VisualizerParams[keyof VisualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'interval': {\n return this.interval;\n }\n\n case 'styles': {\n return this.styles;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'interval': {\n if (typeof value === 'number') {\n this.interval = value;\n }\n\n break;\n }\n\n case 'styles': {\n if (typeof value === 'object') {\n this.styles = { ...this.styles, ...value };\n }\n\n break;\n }\n }\n }\n }\n\n /**\n * This method gets instance of `HTMLCanvasElement` or `SVGSVGElement`.\n * @return {HTMLCanvasElement|SVGSVGElement|null}\n */\n public get(): HTMLCanvasElement | SVGSVGElement | null {\n switch (this.graphics) {\n case 'canvas': {\n return this.canvas;\n }\n\n case 'svg': {\n return this.svg;\n }\n\n default: {\n return null;\n }\n }\n }\n\n /**\n * This method clears graphics.\n * @return {Visualizer} Return value is for method chain.\n */\n public clear() {\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas && this.context) {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n break;\n }\n\n case 'svg': {\n if (this.svg) {\n this.svg.innerHTML = '';\n }\n\n break;\n }\n\n default: {\n break;\n }\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method creates visualized graphics as string (Data URL or `Blob` or SVG).\n * @param {string} mimeType This argument is string that indicates image format. The default value is `image/octet-stream`.\n * @property {BlobCallback} callback This argument is callback function with resulting instance of `Blob`.\n * @property {string} type This argument is string that indicates image format. The default value is `image/png`.\n * @property {number} quality This argument is number between `0` and `1` that indicates image quality.\n * @return {string|void}\n */\n public create(mimeType?: string, params?: {\n callback: BlobCallback,\n type?: string,\n quality?: number,\n }): string | void {\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return '';\n }\n\n if ((typeof mimeType === 'string') && /^image\\/.+$/.test(mimeType)) {\n return this.canvas.toDataURL(mimeType);\n }\n\n if (params) {\n const { callback, type, quality } = params;\n\n return this.canvas.toBlob(callback, type, quality);\n }\n\n return this.canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');\n }\n\n case 'svg': {\n if (this.svg === null) {\n return '';\n }\n\n return this.svg.outerHTML;\n }\n\n default: {\n return '';\n }\n }\n }\n\n /**\n * This method gets visualizer state. If returns `true`, visualizer is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates visualizer.\n * @return {Visualizer} Return value is for method chain.\n */\n public activate() {\n this.isActive = true;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method deactivates visualizer.\n * @return {Visualizer} Return value is for method chain.\n */\n public deactivate() {\n this.isActive = false;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method visualizes time domain data (`Float32Array`) to Canvas.\n * @param {CanvasRenderingContext2D} context This argument is instance of `CanvasRenderingContext2D`.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is width of visualization area.\n * @param {number} innerHeight This argument is height of visualization area.\n * @param {number} middle This argument is middle of visualization area.\n * @param {number} numberOfPlots This argument is interval for visualization.\n */\n protected visualizeTimeDomainFloat32ArrayOnCanvas(context: CanvasRenderingContext2D, data: Float32Array, innerWidth: number, innerHeight: number, middle: number, numberOfPlots?: number): void {\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n\n // Begin visualization\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n for (let n = 0, len = data.length; n < len; n++) {\n if (!numberOfPlots || ((n % numberOfPlots) === 0)) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - data[n]) * (innerHeight / 2)) + top;\n\n if (n === 0) {\n context.moveTo((x + (context.lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let n = 0, len = data.length; n < len; n++) {\n if (!numberOfPlots || ((n % numberOfPlots) === 0)) {\n const x = ((n / len) * innerWidth) + left;\n const y = -1 * (data[n] * (innerHeight / 2));\n\n // Set style\n if (this.styles.gradients) {\n const upside = (innerHeight / 2) + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, middle, lineWidth, y);\n }\n }\n\n break;\n }\n }\n }\n\n /**\n * This method visualizes time domain data (`Float32Array`) to SVG.\n * @param {Float32Array} data This argument is time domain data.\n * @param {number} innerWidth This argument is width of visualization area.\n * @param {number} innerHeight This argument is height of visualization area.\n * @param {number} middle This argument is middle of visualization area.\n * @param {number} numberOfPlots This argument is interval for visualization.\n * @param {string} linearGradientId This argument is `id` attribute for `SVGLinearGradientElement`.\n * @return {SVGPathElement|SVGGElement} This value is instance of `SVGPathElement` or `SVGGElement`.\n */\n protected visualizeTimeDomainFloat32ArrayBySVG(data: Float32Array, innerWidth: number, innerHeight: number, middle: number, numberOfPlots: number, linearGradientId: string): SVGPathElement | SVGGElement | null {\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(Visualizer.XMLNS, 'path');\n\n let d = '';\n\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfPlots) === 0) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - data[n]) * (innerHeight / 2)) + top;\n\n if (n === 0) {\n d += `M${x + ((this.styles.width ?? 1.5) / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n return path;\n }\n\n case 'rect': {\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(linearGradientId);\n }\n\n // Visualize wave\n const g = document.createElementNS(Visualizer.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfPlots) === 0) {\n const rect = document.createElementNS(Visualizer.XMLNS, 'rect');\n\n const x = ((n / len) * innerWidth) + left;\n const y = data[n] * (innerHeight / 2);\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', middle.toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', ((defs === null) ? waveColor : `url(#${linearGradientId})`));\n\n g.appendChild(rect);\n }\n }\n\n return g;\n }\n\n default: {\n return null;\n }\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 value is as instance of `SVGDefsElement`.\n */\n protected createSVGLinearGradient(linearGradientId: string): SVGDefsElement | null {\n if (!this.styles.gradients) {\n return null;\n }\n\n const defs = document.createElementNS(Visualizer.XMLNS, 'defs');\n const linearGradient = document.createElementNS(Visualizer.XMLNS, 'linearGradient');\n\n linearGradient.setAttribute('id', 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.gradients) {\n const stop = document.createElementNS(Visualizer.XMLNS, 'stop');\n\n stop.setAttribute('offset', gradients.offset.toString(10));\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 styles.\n * @return {string}\n */\n protected createFontString(): string {\n const { style, weight, size, family } = this.styles.font ?? {};\n\n return `${style ?? 'normal'} ${weight ?? 'normal'} ${size ?? '13px'} \"${family ?? 'Arial'}\"`;\n }\n\n protected abstract visualizeOnCanvas(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void;\n protected abstract visualizeBySVG(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void;\n}\n","import type { ChannelNumber } from '../../types';\nimport type { VisualizerParams, Color, GraphicsStyles } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type MouseEventTypes = 'mousedown' | 'mousemove' | 'mouseup' | 'touchstart' | 'touchmove' | 'touchend';\n\nexport type DragMode = 'update' | 'sprite';\n\nexport type DragCallbackFunction = (event: MouseEvent | TouchEvent, startTime: number, endTime: number, mode: DragMode, direction: boolean) => void;\n\nexport type CurrentTimeStyles = {\n width?: number, // Not used currently\n color?: Color\n};\n\nexport type TimeOverviewParams = VisualizerParams & {\n currentTime?: CurrentTimeStyles,\n sprite?: Color,\n plotInterval?: number,\n textInterval?: number,\n mode?: DragMode\n};\n\nconst SVG_CURRENT_TIME_CLASS_NAME = 'xsound-svg-current-time';\nconst SVG_SPRITE_CLASS_NAME = 'xsound-svg-sprite';\n\n/**\n * This private class visualizes audio wave overview in time domain.\n */\nexport class TimeOverview extends Visualizer {\n private callback: DragCallbackFunction = () => {};\n\n private currentImageData: ImageData | null = null;\n private currentSVGElement: Element | null = null;\n private currentDataSize = 0;\n\n // for `update`, `drag`\n // This style is used for rectangle that displays audio current time\n private currentTime: CurrentTimeStyles = {\n width: 1,\n color: 'rgba(0, 0, 0, 0.5)'\n };\n\n // This style is used for rectangle that displays sprite range\n private sprite: Color = 'rgba(255, 255, 255, 0.25)';\n\n private plotInterval = 0.0625;\n private textInterval = 60;\n\n private isDown = false;\n private mode: DragMode = 'update';\n\n private offsetX = 0;\n private startTime = 0;\n private endTime = 0;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n */\n constructor(sampleRate: number, channel: ChannelNumber) {\n super(sampleRate, channel);\n\n this.onMouseStart = this.onMouseStart.bind(this);\n this.onMouseMove = this.onMouseMove.bind(this);\n this.onMouseUp = this.onMouseUp.bind(this);\n\n this.onTouchStart = this.onTouchStart.bind(this);\n this.onTouchMove = this.onTouchMove.bind(this);\n this.onTouchEnd = this.onTouchEnd.bind(this);\n }\n\n /**\n * This method gets or sets parameters for visualizing audio wave.\n * This method is overloaded for type interface and type check.\n * @param {keyof TimeOverviewParams|TimeOverviewParams} params This argument is string if getter. Otherwise, setter.\n * @return {TimeOverviewParams[keyof TimeOverviewParams]|TimeOverview} Return value is parameter for visualizing audio wave if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'currentTime'): CurrentTimeStyles;\n public override param(params: 'sprite'): Color;\n public override param(params: 'plotInterval'): number;\n public override param(params: 'textInterval'): number;\n public override param(params: 'mode'): DragMode;\n public override param(params: TimeOverviewParams): TimeOverview;\n public override param(params: keyof TimeOverviewParams | TimeOverviewParams): TimeOverviewParams[keyof TimeOverviewParams] | TimeOverview {\n if (typeof params === 'string') {\n switch (params) {\n case 'currentTime': {\n return this.currentTime;\n }\n\n case 'sprite': {\n return this.sprite;\n }\n\n case 'plotInterval': {\n return this.plotInterval;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'mode': {\n return this.mode;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'currentTime': {\n if (typeof value === 'object') {\n this.currentTime = { ...this.currentTime, ...value };\n }\n\n break;\n }\n\n case 'sprite': {\n if (typeof value === 'string') {\n this.sprite = value;\n }\n\n break;\n }\n\n case 'plotInterval': {\n if (typeof value === 'number') {\n this.plotInterval = value;\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n\n case 'mode': {\n if (typeof value === 'string') {\n if ((value === 'update') || (value === 'sprite')) {\n this.mode = value;\n }\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes audio current time on Canvas or SVG.\n * @param {number} time This argument is audio current time.\n * @return {TimeOverview} Return value is for method chain.\n */\n public update(time: number): TimeOverview {\n switch (this.graphics) {\n case 'canvas': {\n if (this.currentImageData === null) {\n return this;\n }\n\n if ((this.canvas === null) || (this.context === null)) {\n return this;\n }\n\n const context = this.context;\n const width = this.canvas.width;\n const height = this.canvas.height;\n\n const innerWidth = width - ((this.styles.left ?? 30) + (this.styles.right ?? 30));\n const innerHeight = height - ((this.styles.top ?? 15) + (this.styles.bottom ?? 15));\n const x = ((time * this.sampleRate) / this.currentDataSize) * innerWidth;\n const left = this.styles.left ?? 30;\n const top = this.styles.top ?? 15;\n\n const currentTimeColor = this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)';\n\n context.clearRect(0, 0, width, height);\n context.putImageData(this.currentImageData, 0, 0);\n\n switch (this.mode) {\n case 'update': {\n context.fillStyle = currentTimeColor;\n context.fillRect(left, (top + 1), x, (innerHeight - 1));\n\n break;\n }\n\n case 'sprite': {\n if (this.endTime !== 0) {\n const baseX = Math.trunc(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.currentDataSize) * innerWidth);\n\n context.fillStyle = this.sprite;\n\n if (x >= this.offsetX) {\n context.fillRect((left + this.offsetX), (top + 1), baseX, (innerHeight - 1));\n } else {\n context.fillRect((left + this.offsetX - baseX), (top + 1), baseX, (innerHeight - 1));\n }\n }\n\n context.fillStyle = currentTimeColor;\n\n if (x >= this.offsetX) {\n context.fillRect((left + this.offsetX), (top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n } else {\n context.fillRect((left + x), (top + 1), Math.abs(x - this.offsetX), (innerHeight - 1));\n }\n\n break;\n }\n }\n\n break;\n }\n\n case 'svg': {\n if (this.currentSVGElement === null) {\n return this;\n }\n\n if (this.svg) {\n const rect = this.svg.querySelector(`.${SVG_CURRENT_TIME_CLASS_NAME}`);\n\n if (rect === null) {\n return this;\n }\n\n const width = Number((this.svg.getAttribute('width') ?? '0'));\n const top = this.styles.top ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const x = ((time * this.sampleRate) / this.currentDataSize) * innerWidth;\n\n if (this.mode === 'update') {\n const spriteRect = this.svg.querySelector(`.${SVG_SPRITE_CLASS_NAME}`);\n\n if (spriteRect) {\n spriteRect.parentNode?.removeChild(spriteRect);\n }\n\n rect.setAttribute('x', left.toString(10));\n rect.setAttribute('width', x.toString(10));\n // rect.setAttribute('transform', `translate(${x} 0)`);\n rect.setAttribute('aria-label', 'current time');\n } else if (this.mode === 'sprite') {\n if (this.endTime !== 0) {\n const prevRect = this.svg.querySelector(`.${SVG_SPRITE_CLASS_NAME}`);\n\n if (prevRect) {\n prevRect.parentNode?.removeChild(prevRect);\n }\n\n const baseRect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n baseRect.classList.add(SVG_SPRITE_CLASS_NAME);\n\n const baseX = Math.trunc(((Math.abs(this.endTime - this.startTime) * this.sampleRate) / this.currentDataSize) * innerWidth);\n\n baseRect.setAttribute('y', (top + 1).toString(10));\n baseRect.setAttribute('height', (rect.getAttribute('height') ?? '0'));\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', (left + this.offsetX).toString(10));\n } else {\n baseRect.setAttribute('x', (left + this.offsetX - baseX).toString(10));\n }\n\n baseRect.setAttribute('width', baseX.toString(10));\n\n this.svg.appendChild(baseRect);\n this.svg.appendChild(rect);\n }\n\n if (x >= this.offsetX) {\n rect.setAttribute('x', (left + this.offsetX).toString(10));\n } else {\n rect.setAttribute('x', (left + x).toString(10));\n }\n\n rect.setAttribute('width', Math.abs(x - this.offsetX).toString(10));\n rect.setAttribute('aria-label', 'sprite time');\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method registers event listener for updating current time or spriting audio by drag.\n * @param {DragCallbackFunction} callback This argument is invoked during drag.\n * @return {TimeOverview} Return value is for method chain.\n */\n public drag(callback?: DragCallbackFunction): TimeOverview {\n let visualizationNode: HTMLCanvasElement | Element | null = null;\n\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return this;\n }\n\n visualizationNode = this.canvas;\n break;\n }\n\n case 'svg': {\n if (this.svg === null) {\n return this;\n }\n\n visualizationNode = this.svg;\n break;\n }\n }\n\n if (visualizationNode === null) {\n return this;\n }\n\n if (callback) {\n this.callback = callback;\n }\n\n visualizationNode.removeEventListener('mousedown', { handleEvent: this.onMouseStart }, false);\n visualizationNode.removeEventListener('mousemove', { handleEvent: this.onMouseMove }, false);\n window.removeEventListener('mouseup', { handleEvent: this.onMouseUp }, false);\n\n visualizationNode.removeEventListener('touchstart', { handleEvent: this.onTouchStart }, false);\n visualizationNode.removeEventListener('touchmove', { handleEvent: this.onTouchMove }, false);\n window.removeEventListener('touchend', { handleEvent: this.onTouchEnd }, false);\n\n visualizationNode.addEventListener('mousedown', { handleEvent: this.onMouseStart }, false);\n visualizationNode.addEventListener('mousemove', { handleEvent: this.onMouseMove }, false);\n window.addEventListener('mouseup', { handleEvent: this.onMouseUp }, false);\n\n visualizationNode.addEventListener('touchstart', { handleEvent: this.onTouchStart }, false);\n visualizationNode.addEventListener('touchmove', { handleEvent: this.onTouchMove }, false);\n window.addEventListener('touchend', { handleEvent: this.onTouchEnd }, false);\n\n return this;\n }\n\n /**\n * This method visualizes audio wave overview to Canvas.\n * @param {Float32Array} data This argument is audio data for visualization.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive || (data instanceof Uint8Array)) {\n return;\n }\n\n const context = this.context;\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize wave at intervals of `this.plotInterval`\n const numberOfPlots = Math.trunc(this.plotInterval * this.sampleRate);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n this.visualizeTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle, numberOfPlots);\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % numberOfTexts) === 0) {\n const x = Math.trunc((i / len) * innerWidth) + left;\n const t = `${Math.trunc((i / this.sampleRate) / 60)} min`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(t, (x - (context.measureText(t).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const t of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = Math.trunc(left - context.measureText(t).width);\n const y = Math.trunc((1 - Number(t.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(t, x, (y - Math.trunc(fontSize / 4)));\n }\n }\n }\n\n // for `update`, `drag`\n this.currentImageData = context.getImageData(0, 0, width, height);\n this.currentDataSize = data.length;\n\n // This rectangle displays audio current time\n context.fillStyle = this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)';\n context.fillRect(left, top, 1, innerHeight);\n }\n\n /**\n * This method visualizes audio wave overview to SVG.\n * @param {Float32Array} data This argument is audio data for visualization.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive || (data instanceof Uint8Array)) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize wave at intervals of `this.plotInterval`\n const numberOfPlots = Math.trunc(this.plotInterval * this.sampleRate);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin visualization\n const element = this.visualizeTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, numberOfPlots, `${TimeOverview.SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW}-${this.channel}`);\n\n if (element) {\n svg.appendChild(element);\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let i = 0, len = data.length; i < len; i++) {\n if ((i % numberOfTexts) === 0) {\n const x = Math.trunc((i / len) * innerWidth) + left;\n const t = `${Math.trunc((i / this.sampleRate) / 60)} min`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(TimeOverview.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + fontSize).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const t of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = left;\n const y = Math.trunc((1 - Number(t.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(TimeOverview.XMLNS, 'text');\n\n text.textContent = t;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n\n // This rectangle displays audio current time\n const rect = document.createElementNS(TimeOverview.XMLNS, 'rect');\n\n rect.classList.add(SVG_CURRENT_TIME_CLASS_NAME);\n\n rect.setAttribute('y', (top + 1).toString(10));\n rect.setAttribute('height', (innerHeight - 1).toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (this.currentTime.color ?? 'rgba(0, 0, 0, 0.5)'));\n\n svg.appendChild(rect);\n\n // for `update`, `drag`\n this.currentSVGElement = svg;\n this.currentDataSize = data.length;\n }\n\n /**\n * This method visualizes rectangle for audio current time.\n * @param {MouseEvent|TouchEvent} event This argument is instance of `MouseEvent` or `TouchEvent`.\n * @param {MouseEventTypes} type This argument is one of 'mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchmove', 'touchend'.\n * @param {number} offsetX This argument is X coordinate on Canvas or SVG from window.\n */\n private visualize(event: MouseEvent | TouchEvent, type: MouseEventTypes, offsetX: number): void {\n let offsetLeft = 0;\n let width = 0;\n\n switch (this.graphics) {\n case 'canvas': {\n if (this.canvas === null) {\n return;\n }\n\n offsetLeft = this.canvas.offsetLeft;\n width = this.canvas.width;\n break;\n }\n\n case 'svg': {\n if (this.svg === null) {\n return;\n }\n\n offsetLeft = this.svg.parentElement?.offsetLeft ?? 0;\n width = Number((this.svg.getAttribute('width') ?? '0'));\n break;\n }\n }\n\n let x = offsetX - (offsetLeft + (this.styles.left ?? 30));\n\n if (this.graphics === 'canvas' && this.canvas?.parentElement) {\n x += this.canvas.parentElement.scrollLeft;\n }\n\n if (this.graphics === 'svg' && this.svg?.parentElement) {\n x += this.svg.parentElement.scrollLeft;\n }\n\n width -= ((this.styles.left ?? 30) + (this.styles.right ?? 30));\n\n // Exceed ?\n if (x < 0) { x = 0; }\n if (x > width) { x = width; }\n\n const plot = (x / width) * this.currentDataSize;\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\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseStart(event: MouseEvent): void {\n if (event.type === 'mousedown') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = true;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseMove(event: MouseEvent): void {\n if (!this.isDown) {\n return;\n }\n\n // Improve rendering performance by stopping event bubbling\n event.stopPropagation();\n\n if (event.type === 'mousemove') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {MouseEvent} event This argument is instance of `MouseEvent`.\n */\n private onMouseUp(event: MouseEvent): void {\n if (!this.isDown) {\n return;\n }\n\n if (event.type === 'mouseup') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = false;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchStart(event: TouchEvent): void {\n if (event.type === 'touchstart') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = true;\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchMove(event: TouchEvent): void {\n if (!this.isDown) {\n return;\n }\n\n // Improve rendering performance by stopping event bubbling\n event.stopPropagation();\n\n // for Touch Panel\n event.preventDefault();\n\n if (event.type === 'touchmove') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n }\n\n /**\n * This method is event listener for visualizing rectangle.\n * @param {TouchEvent} event This argument is instance of `TouchEvent`.\n */\n private onTouchEnd(event: TouchEvent): void {\n if (!this.isDown) {\n return;\n }\n\n if (event.type === 'touchend') {\n this.visualize(event, event.type, this.getOffsetX(event));\n }\n\n this.isDown = false;\n }\n\n /**\n * This method returns X coordinate from instance of `MouseEvent` or `TouchEvent`.\n * @param {MouseEvent|TouchEvent} event This argument is instance of `MouseEvent` or `TouchEvent`.\n * @return {number} Return value is X coordinate as mouse or touch position.\n */\n private getOffsetX(event: MouseEvent | TouchEvent): number {\n if (event instanceof MouseEvent) {\n return event.pageX;\n }\n\n if (event instanceof TouchEvent) {\n return event.touches[0].pageX;\n }\n\n return 0;\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { DataType } from '../Analyser';\nimport type { VisualizerParams, GraphicsStyles } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type TimeParams = VisualizerParams & {\n type?: DataType,\n textInterval?: number\n};\n\n/**\n * This private class visualizes sound wave in time domain.\n */\nexport class Time extends Visualizer {\n private type: DataType = 'uint';\n\n // Visualize text at intervals this value [sec]\n private textInterval = 0.005;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n // eslint-disable-next-line no-useless-constructor\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n }\n\n /**\n * This method gets or sets parameters for visualizing sound wave.\n * This method is overloaded for type interface and type check.\n * @param {keyof TimeParams|TimeParams} params This argument is string if getter. Otherwise, setter.\n * @return {TimeParams[keyof TimeParams]|Time} Return value is parameter for visualizing sound wave if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'type'): DataType;\n public override param(params: 'textInterval'): number;\n public override param(params: TimeParams): Time;\n public override param(params: keyof TimeParams | TimeParams): TimeParams[keyof TimeParams] | Time {\n if (typeof params === 'string') {\n switch (params) {\n case 'type': {\n return this.type;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'uint') || (value === 'float')) {\n this.type = value;\n }\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes sound wave in time domain to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n if (data instanceof Float32Array) {\n this.visualizeTimeDomainFloat32ArrayOnCanvas(context, data, innerWidth, innerHeight, middle);\n }\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - (data[n] / 255)) * innerHeight) + top;\n\n if (n === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = (0.5 - (data[n] / 255)) * innerHeight;\n\n // Set style\n if (this.styles.gradients) {\n const upside = (innerHeight / 2) + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, middle, 1, y);\n }\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfTexts) === 0) {\n const x = Math.trunc((n / len) * innerWidth) + left;\n\n const timeText = `${Math.ceil((n / this.sampleRate) * 1000)} ms`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(timeText, (x - (context.measureText(timeText).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const amplitudeText of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = Math.trunc((1 - Number(amplitudeText.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, (y - Math.trunc(fontSize / 4)));\n }\n }\n }\n }\n\n /**\n * This method visualizes sound wave in time domain to SVG.\n * @param {Uint8Array|Float32Array} data This argument is sound data for visualization.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, _minDecibels?: number, _maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 15;\n const bottom = this.styles.bottom ?? 15;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n const middle = Math.trunc(innerHeight / 2) + top;\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)';\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval * this.sampleRate);\n\n // Begin visualization\n svg.innerHTML = '';\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n if (data instanceof Float32Array) {\n const element = this.visualizeTimeDomainFloat32ArrayBySVG(data, innerWidth, innerHeight, middle, 0, Time.SVG_LINEAR_GRADIENT_ID_TIME);\n\n if (element !== null) {\n svg.appendChild(element);\n }\n }\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(Time.XMLNS, 'path');\n\n let d = '';\n\n for (let n = 0, len = data.length; n < len; n++) {\n const x = ((n / len) * innerWidth) + left;\n const y = ((1 - (data[n] / 255)) * innerHeight) + top;\n\n if (n === 0) {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'rect': {\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(`${Time.SVG_LINEAR_GRADIENT_ID_TIME}-${this.channel}`);\n }\n\n // Visualize wave\n const g = document.createElementNS(Time.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let n = 0, len = data.length; n < len; n++) {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n const x = ((n / len) * innerWidth) + left;\n const y = ((data[n] / 255) - 0.5) * innerHeight;\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', middle.toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${middle})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', ((defs === null) ? waveColor : `url(#${Time.SVG_LINEAR_GRADIENT_ID_TIME}-${this.channel})`));\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n for (let n = 0, len = data.length; n < len; n++) {\n if ((n % numberOfTexts) === 0) {\n const x = Math.trunc((n / len) * innerWidth) + left;\n\n const timeText = `${Math.ceil((n / this.sampleRate) * 1000)} ms`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(Time.XMLNS, 'text');\n\n text.textContent = timeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + fontSize).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n }\n\n // Visualize grid and text (Y axis)\n for (const amplitudeText of ['-1.00', '-0.50', ' 0.00', ' 0.50', ' 1.00']) {\n const x = left;\n const y = Math.trunc((1 - Number(amplitudeText.trim())) * (innerHeight / 2)) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(Time.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(Time.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', (this.styles.font?.style ?? 'normal'));\n text.setAttribute('font-weight', (this.styles.font?.weight ?? 'normal'));\n\n svg.appendChild(text);\n }\n }\n }\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { DataType } from '../Analyser';\nimport type { VisualizerParams, GraphicsStyles, SpectrumScale } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type FFTParams = VisualizerParams & {\n type?: DataType,\n size?: number,\n scale?: SpectrumScale,\n logarithmicFrequencies?: number[],\n textInterval?: number,\n readonly minFrequency?: number,\n readonly maxFrequency?: number\n};\n\n/**\n * This private class visualizes spectrum.\n */\nexport class FFT extends Visualizer {\n private type: DataType = 'uint';\n\n // Range for visualization\n private size = 256;\n\n private scale: SpectrumScale = 'linear';\n\n // for logarithmic\n private logarithmicFrequencies: number[] = [32, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];\n private minFrequency = this.logarithmicFrequencies[0];\n private maxFrequency = this.logarithmicFrequencies[this.logarithmicFrequencies.length - 1];\n private ratio = this.maxFrequency / this.minFrequency;\n private log10Ratio = Math.log10(this.ratio);\n\n // Visualize text at intervals of this value [Hz]\n private textInterval = 1000;\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n // eslint-disable-next-line no-useless-constructor\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n }\n\n /**\n * This method gets or sets parameters for visualizing spectrum.\n * This method is overloaded for type interface and type check.\n * @param {keyof FFTParams|FFTParams} params This argument is string if getter. Otherwise, setter.\n * @return {FFTParams[keyof FFTParams]|FFT} Return value is parameter for visualizing spectrum if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'type'): DataType;\n public override param(params: 'size'): number;\n public override param(params: 'scale'): SpectrumScale;\n public override param(params: 'logarithmicFrequencies'): number[];\n public override param(params: 'minFrequency'): number;\n public override param(params: 'maxFrequency'): number;\n public override param(params: 'textInterval'): number;\n public override param(params: FFTParams): FFT;\n public override param(params: keyof FFTParams | FFTParams): FFTParams[keyof FFTParams] | FFT {\n if (typeof params === 'string') {\n switch (params) {\n case 'type': {\n return this.type;\n }\n\n case 'size': {\n return this.size;\n }\n\n case 'scale': {\n return this.scale;\n }\n\n case 'logarithmicFrequencies': {\n return this.logarithmicFrequencies;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'textInterval': {\n return this.textInterval;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'uint') || (value === 'float')) {\n this.type = value;\n }\n }\n\n break;\n }\n\n case 'size': {\n if (typeof value === 'number') {\n this.size = value;\n }\n\n break;\n }\n\n case 'scale': {\n if (typeof value === 'string') {\n if ((value === 'linear') || (value === 'logarithmic')) {\n this.scale = value;\n }\n }\n\n break;\n }\n\n case 'logarithmicFrequencies': {\n if (Array.isArray(value)) {\n this.logarithmicFrequencies = value;\n\n this.minFrequency = value[0];\n this.maxFrequency = value[value.length - 1];\n this.ratio = this.maxFrequency / this.minFrequency;\n this.log10Ratio = Math.log10(this.ratio);\n }\n\n break;\n }\n\n case 'textInterval': {\n if (typeof value === 'number') {\n this.textInterval = value;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method visualizes spectrum to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrum.\n * @param {number} minDecibels This argument is in order to determine dB range of spectrum. The default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine db range of spectrum. The default value is -30 dB.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const mindB = minDecibels ?? -100;\n const maxdB = maxDecibels ?? -30;\n const range = maxdB - mindB;\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)'; // line only\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const actualSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / (2 * data.length);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval / frequencyResolution);\n\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n // Visualize wave\n context.beginPath();\n\n switch (this.scale) {\n case 'linear': {\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n if (k === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n for (let k = 0, len = data.length; k < len; k++) {\n if (k === 0) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(y)) {\n continue;\n }\n\n if ((x < left) || (x > (left + innerWidth))) {\n continue;\n }\n\n if (k === 1) {\n context.moveTo((left + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n break;\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Set style\n context.strokeStyle = waveColor;\n context.lineWidth = lineWidth;\n context.lineCap = lineCap;\n context.lineJoin = lineJoin;\n\n context.beginPath();\n\n // Visualize wave\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = ((1 - (data[k] / 255)) * innerHeight) + top;\n\n if (k === 0) {\n context.moveTo((x + (lineWidth / 2)), y);\n } else {\n context.lineTo(x, y);\n }\n }\n\n context.stroke();\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n for (let k = 0; k < actualSize; k++) {\n const x = ((k / actualSize) * innerWidth) + left;\n const y = -1 * ((data[k] / 255) * innerHeight);\n\n // Set style\n if (this.styles.gradients) {\n const upside = innerHeight + top;\n const gradient = context.createLinearGradient(0, upside, 0, (upside + y));\n\n for (const gradients of this.styles.gradients) {\n gradient.addColorStop(gradients.offset, gradients.color);\n }\n\n context.fillStyle = gradient;\n } else {\n context.fillStyle = waveColor;\n }\n\n context.fillRect(x, (innerHeight + top), lineWidth, y);\n }\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n if ((this.type === 'uint') || ((this.type === 'float') && (this.scale === 'linear'))) {\n for (let k = 0; k < actualSize; k++) {\n if ((k % numberOfTexts) === 0) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n\n const frequency = Math.trunc(this.textInterval * (k / numberOfTexts));\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(frequencyText, (x - (context.measureText(frequencyText).width / 2)), (top + innerHeight + fontSize));\n }\n }\n }\n } else {\n this.logarithmicFrequencies.forEach((frequency: number) => {\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(x, top, 1, innerHeight);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(frequencyText, (x - (context.measureText(frequencyText).width / 2)), (top + innerHeight + fontSize));\n }\n });\n }\n\n // Visualize grid and text (Y axis)\n switch (this.type) {\n case 'float': {\n for (let amplitude = mindB; amplitude <= maxdB; amplitude += 10) {\n const amplitudeText = `${amplitude} dB`;\n\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = Math.trunc(((-1 * (amplitude - maxdB)) / range) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, y);\n }\n }\n\n break;\n }\n\n case 'uint': {\n for (const amplitudeText of ['0.00', '0.25', '0.50', '0.75', '1.00']) {\n const x = Math.trunc(left - context.measureText(amplitudeText).width);\n const y = ((1 - Number(amplitudeText)) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n context.fillStyle = gridColor;\n context.fillRect(left, y, innerWidth, 1);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.fillText(amplitudeText, x, y);\n }\n }\n\n break;\n }\n }\n }\n }\n\n /**\n * This method visualizes spectrum to SVG.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrum.\n * @param {number} minDecibels This argument is in order to determine dB range of spectrum. Default value is -100 dB.\n * @param {number} maxDecibels This argument is in order to determine db range of spectrum. Default value is -30 dB.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array, minDecibels?: number, maxDecibels?: number): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const mindB = minDecibels ?? -100;\n const maxdB = maxDecibels ?? -30;\n const range = maxdB - mindB;\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const waveColor = this.styles.wave ?? 'rgba(0, 0, 255, 1.0)'; // line only\n const lineWidth = this.styles.width ?? 1.5;\n const lineCap = this.styles.cap ?? 'round';\n const lineJoin = this.styles.join ?? 'miter';\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const actualSize = (this.size > data.length) ? data.length : this.size;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / (2 * data.length);\n\n // Visualize text at intervals of `this.textInterval`\n const numberOfTexts = Math.trunc(this.textInterval / frequencyResolution);\n\n // Erase previous wave\n svg.innerHTML = '';\n\n // Begin visualization\n switch (this.type) {\n case 'float': {\n // Visualize wave\n const path = document.createElementNS(FFT.XMLNS, 'path');\n\n let d = '';\n\n switch (this.scale) {\n case 'linear': {\n for (let k = 0; k < actualSize; k++) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(x) || !Number.isFinite(y)) {\n continue;\n }\n\n if (d === '') {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n for (let k = 0; k < data.length; k++) {\n if (k === 0) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n const y = Math.trunc(-1 * (data[k] - maxdB) * (innerHeight / range)) + top; // [dB] * [px / dB] = [px]\n\n // HACK: Because of infinity sometimes\n if (!Number.isFinite(y)) {\n continue;\n }\n\n if ((x < left) || (x > (left + innerWidth))) {\n continue;\n }\n\n if (d === '') {\n d += `M${x} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n break;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor); // line only\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'uint': {\n switch (this.styles.shape) {\n case 'line': {\n // Visualize wave\n const path = document.createElementNS(FFT.XMLNS, 'path');\n\n let d = '';\n\n for (let k = 0; k < actualSize; k++) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc((1 - (data[k] / 255)) * innerHeight) + top;\n\n if (k === 0) {\n d += `M${x + (lineWidth / 2)} ${y}`;\n } else {\n d += ` L${x} ${y}`;\n }\n }\n\n path.setAttribute('d', d);\n\n path.setAttribute('stroke', waveColor);\n path.setAttribute('fill', 'none');\n path.setAttribute('stroke-width', lineWidth.toString(10));\n path.setAttribute('stroke-linecap', lineCap);\n path.setAttribute('stroke-linejoin', lineJoin);\n\n svg.appendChild(path);\n\n break;\n }\n\n case 'rect': {\n // Visualize wave\n let defs = null;\n\n if (this.styles.gradients) {\n defs = this.createSVGLinearGradient(`${FFT.SVG_LINEAR_GRADIENT_ID_FFT}-${this.channel}`);\n }\n\n // Visualize wave\n const g = document.createElementNS(FFT.XMLNS, 'g');\n\n if (defs !== null) {\n g.appendChild(defs);\n }\n\n for (let k = 0; k < actualSize; k++) {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n const y = Math.trunc((data[k] / 255) * innerHeight);\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (top + innerHeight).toString(10));\n rect.setAttribute('width', lineWidth.toString(10));\n rect.setAttribute('height', Math.abs(y).toString(10));\n\n if (y >= 0) {\n rect.setAttribute('transform', `rotate(180 ${x + (lineWidth / 2)} ${top + innerHeight})`);\n }\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', (defs === null) ? waveColor : `url(#${FFT.SVG_LINEAR_GRADIENT_ID_FFT}-${this.channel})`);\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n break;\n }\n }\n\n if ((gridColor !== 'none') || (textColor !== 'none')) {\n // Visualize grid and text (X axis)\n if ((this.type === 'uint') || ((this.type === 'float') && (this.scale === 'linear'))) {\n for (let k = 0; k < actualSize; k++) {\n if ((k % numberOfTexts) === 0) {\n const x = Math.trunc((k / actualSize) * innerWidth) + left;\n\n const frequency = Math.trunc(this.textInterval * (k / numberOfTexts));\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = frequencyText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + bottom).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n }\n } else {\n this.logarithmicFrequencies.forEach((frequency: number) => {\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = Math.trunc((log10FrequencyRatio / this.log10Ratio) * innerWidth) + left;\n\n const frequencyText = (frequency < 1000) ? `${frequency} Hz` : `${(frequency / 1000).toString(10).slice(0, 3)} kHz`;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', top.toString(10));\n rect.setAttribute('width', '1');\n rect.setAttribute('height', innerHeight.toString(10));\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = frequencyText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (top + innerHeight + bottom).toString(10));\n\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', (this.styles.font?.family ?? 'Arial'));\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n });\n }\n\n // Visualize grid and text (Y axis)\n switch (this.type) {\n case 'float': {\n for (let amplitude = mindB; amplitude <= maxdB; amplitude += 10) {\n const amplitudeText = `${amplitude} dB`;\n\n const x = left;\n const y = Math.trunc(((-1 * (amplitude - maxdB)) / range) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (gridColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n\n case 'uint': {\n for (const amplitudeText of ['0.00', '0.25', '0.50', '0.75', '1.00']) {\n const x = left;\n const y = ((1 - Number(amplitudeText)) * innerHeight) + top;\n\n // Visualize grid\n if (gridColor !== 'none') {\n const rect = document.createElementNS(FFT.XMLNS, 'rect');\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', y.toString(10));\n rect.setAttribute('width', innerWidth.toString(10));\n rect.setAttribute('height', '1');\n\n rect.setAttribute('stroke', 'none');\n rect.setAttribute('fill', gridColor);\n\n svg.appendChild(rect);\n }\n\n // Visualize text\n if (textColor !== 'none') {\n const text = document.createElementNS(FFT.XMLNS, 'text');\n\n text.textContent = amplitudeText;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', (y - Math.trunc(fontSize / 4)).toString(10));\n\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-family', this.styles.font?.family ?? 'Arial');\n text.setAttribute('font-size', fontSize.toString(10));\n text.setAttribute('font-style', this.styles.font?.style ?? 'normal');\n text.setAttribute('font-weight', this.styles.font?.weight ?? 'normal');\n\n svg.appendChild(text);\n }\n }\n\n break;\n }\n }\n }\n }\n}\n","import type { ChannelNumber } from '../../types';\nimport type { DataType } from '../Analyser';\nimport type { VisualizerParams, GraphicsStyles, SpectrumScale } from './Visualizer';\n\nimport { Visualizer } from './Visualizer';\n\nexport type SpectrogramParams = VisualizerParams & {\n type?: DataType,\n size?: number,\n scale?: SpectrumScale,\n duration?: number,\n plotInterval?: number,\n linearFrequencyTextInterval?: number,\n timeTextInterval?: number,\n logarithmicFrequencies?: number[],\n readonly minFrequency?: number,\n readonly maxFrequency?: number\n};\n\n/**\n * This private class visualizes spectrogram.\n */\nexport class Spectrogram extends Visualizer {\n private type: DataType = 'uint';\n\n private scale: SpectrumScale = 'logarithmic';\n\n private duration = 10;\n\n private plotInterval = 4;\n private linearFrequencyTextInterval = 8;\n private timeTextInterval = 16;\n private timeOffset = 1;\n private numberOfSamples = 0;\n\n private renderSize = 64;\n\n // for logarithmic\n private logarithmicFrequencies: number[] = [32, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];\n private minFrequency = this.logarithmicFrequencies[0];\n private maxFrequency = this.logarithmicFrequencies[this.logarithmicFrequencies.length - 1];\n private ratio = this.maxFrequency / this.minFrequency;\n\n private imagedata: ImageData | null = null;\n\n private colorFromNumber: ((data: Uint8Array[0] | Float32Array[0]) => string) | null = null;\n\n /**\n * This function maps unsigned int 8 bits to color string by Jet colormap.\n * @param {Uint8Array[0]|Float32Array[0]} data This argument is converted to color string based on Jet colormap.\n * @param {number} maxDecibels This argument is parameter for spectrogram from dB. The default value is -30 dB.\n * @param {number} minDecibels This argument is parameter for spectrogram from dB. The default value is -100 dB.\n * @return {string} Return value is color string.\n */\n public static numberToJetColor(data: Uint8Array[0] | Float32Array[0], type: DataType, maxDecibels?: number, minDecibels?: number): string {\n switch (type) {\n case 'uint': {\n const rgba = 4 * (data / 255);\n\n const r = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 1.5), (0 - rgba + 4.5)) * 255)));\n const g = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 0.5), (0 - rgba + 3.5)) * 255)));\n const b = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba + 0.5), (0 - rgba + 2.5)) * 255)));\n\n return `rgb(${r} ${g} ${b})`;\n }\n\n case 'float': {\n if ((typeof maxDecibels === 'number') && (typeof minDecibels === 'number')) {\n const rgba = 4 * ((1 / (maxDecibels - minDecibels)) * Math.max(0, (data - minDecibels)));\n\n const r = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 1.5), (0 - rgba + 4.5)) * 255)));\n const g = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba - 0.5), (0 - rgba + 3.5)) * 255)));\n const b = Math.max(0, Math.min(255, Math.trunc(Math.min((rgba + 0.5), (0 - rgba + 2.5)) * 255)));\n\n return `rgb(${r} ${g} ${b})`;\n }\n\n return 'rgb(0 0 0)';\n }\n }\n }\n\n /**\n * @param {number} sampleRate This argument is sample rate.\n * @param {ChannelNumber} channel This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AnalyserNode} analyser This argument is instance of `AnalyserNode`.\n */\n constructor(sampleRate: number, channel: ChannelNumber, analyser: AnalyserNode) {\n super(sampleRate, channel, analyser);\n\n this.interval = 40;\n }\n\n /**\n * This method gets or sets parameters for visualizing spectrogram.\n * This method is overloaded for type interface and type check.\n * @param {keyof SpectrogramParams|SpectrogramParams} params This argument is string if getter. Otherwise, setter.\n * @return {SpectrogramParams[keyof SpectrogramParams]|Spectrogram} Return value is parameter for visualizing spectrogram if getter.\n * Otherwise, return value is for method chain.\n * @override\n */\n public override param(params: 'interval'): number;\n public override param(params: 'styles'): GraphicsStyles;\n public override param(params: 'type'): DataType;\n public override param(params: 'size'): number;\n public override param(params: 'scale'): SpectrumScale;\n public override param(params: 'duration'): number;\n public override param(params: 'plotInterval'): number;\n public override param(params: 'linearFrequencyTextInterval'): number;\n public override param(params: 'timeTextInterval'): number;\n public override param(params: 'logarithmicFrequencies'): number[];\n public override param(params: 'minFrequency'): number;\n public override param(params: 'maxFrequency'): number;\n public override param(params: SpectrogramParams): Spectrogram;\n public override param(params: keyof SpectrogramParams | SpectrogramParams): SpectrogramParams[keyof SpectrogramParams] | Spectrogram {\n if (typeof params === 'string') {\n switch (params) {\n case 'type': {\n return this.type;\n }\n\n case 'size': {\n return this.renderSize;\n }\n\n case 'scale': {\n return this.scale;\n }\n\n case 'duration': {\n return this.duration;\n }\n\n case 'plotInterval': {\n return this.plotInterval;\n }\n\n case 'linearFrequencyTextInterval': {\n return this.linearFrequencyTextInterval;\n }\n\n case 'timeTextInterval': {\n return this.timeTextInterval;\n }\n\n case 'logarithmicFrequencies': {\n return this.logarithmicFrequencies;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'interval': {\n return super.param(params);\n }\n\n case 'styles': {\n return super.param(params);\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'uint') || (value === 'float')) {\n this.type = value;\n }\n }\n\n break;\n }\n\n case 'size': {\n if (typeof value === 'number') {\n this.renderSize = value;\n }\n\n break;\n }\n\n case 'scale': {\n if (typeof value === 'string') {\n if ((value === 'linear') || (value === 'logarithmic')) {\n this.scale = value;\n }\n }\n\n break;\n }\n\n case 'duration': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.duration = value;\n }\n }\n\n break;\n }\n\n case 'plotInterval': {\n if (typeof value === 'number') {\n this.plotInterval = value;\n }\n\n break;\n }\n\n case 'linearFrequencyTextInterval': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.linearFrequencyTextInterval = value;\n }\n }\n\n break;\n }\n\n case 'timeTextInterval': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.timeTextInterval = value;\n }\n }\n\n break;\n }\n\n case 'logarithmicFrequencies': {\n if (Array.isArray(value)) {\n this.logarithmicFrequencies = value;\n\n this.minFrequency = value[0];\n this.maxFrequency = value[value.length - 1];\n this.ratio = this.maxFrequency / this.minFrequency;\n }\n\n break;\n }\n }\n }\n\n super.param(params);\n\n return this;\n }\n\n /**\n * This method sets function that converts number to color string.\n * @param {function} func This argument is function that converts number to color string;\n * @return {Spectrogram} Return value is for method chain.\n */\n public setColorFromNumberFunction(func: ((data: Uint8Array[0] | Float32Array[0]) => string) | null): Spectrogram {\n this.colorFromNumber = func;\n\n return this;\n }\n\n /**\n * This method visualizes spectrogram to Canvas.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrogram.\n * @override\n */\n protected override visualizeOnCanvas(data: Uint8Array | Float32Array): void {\n if ((this.canvas === null) || (this.context === null) || !this.isActive) {\n return;\n }\n\n const context = this.context;\n\n const width = this.canvas.width;\n const height = this.canvas.height;\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n\n const frequencyBinCount = data.length;\n const fftSize = 2 * frequencyBinCount;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / fftSize;\n\n const samples = this.duration * this.sampleRate;\n\n if (this.numberOfSamples >= samples) {\n this.imagedata = null;\n\n this.timeOffset = 1;\n this.numberOfSamples = 0;\n }\n\n if (this.imagedata === null) {\n // Erase previous wave\n context.clearRect(0, 0, width, height);\n\n // Render Graph\n context.fillStyle = gridColor;\n context.fillRect(left, (top + innerHeight), innerWidth, 2);\n context.fillRect(left, top, 2, innerHeight);\n\n // Render coordinate\n context.fillStyle = textColor;\n context.font = this.createFontString();\n\n // X axis (time)\n context.textAlign = 'start';\n\n const textInterval = samples / this.timeTextInterval;\n\n for (let k = 0; k < samples; k++) {\n if ((k % textInterval) !== 0) {\n continue;\n }\n\n const x = k * (innerWidth / samples) + left;\n const y = top + innerHeight + Number.parseInt((this.styles.font?.size ?? '13'), 10);\n\n const time = (k / samples) * this.duration;\n\n if ((time !== 0) && (time < 0.0001)) {\n context.fillText(`${(time * 1000).toFixed(1)} msec`, x, y);\n } else {\n context.fillText(`${time.toFixed(2)} sec`, x, y);\n }\n }\n\n context.textAlign = 'end';\n\n // Y axis (frequency)\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n for (let k = 0; k <= length; k++) {\n if ((k % this.linearFrequencyTextInterval) !== 0) {\n continue;\n }\n\n const x = left;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const frequency = k * frequencyResolution;\n\n context.fillText(`${Math.trunc(frequency)} Hz`, x, y);\n }\n\n break;\n }\n\n case 'logarithmic': {\n this.logarithmicFrequencies.forEach((frequency: number, index: number) => {\n const x = left;\n const y = ((1 - (index / this.logarithmicFrequencies.length)) * innerHeight) + top;\n\n if (frequency >= 1000) {\n context.fillText(`${Math.trunc(frequency / 1000)} kHz`, x, y);\n } else {\n context.fillText(`${frequency} Hz`, x, y);\n }\n });\n\n break;\n }\n }\n } else {\n context.putImageData(this.imagedata, 0, 0);\n }\n\n // Render spectrogram\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const h = Number.parseInt((this.styles.font?.size ?? '13'), 10);\n\n for (let k = 0; k < length; k++) {\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const x = left + this.timeOffset;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k], this.type, this.analyser?.maxDecibels, this.analyser?.minDecibels);\n\n context.fillStyle = color;\n context.fillRect(x, (y - h), 1, h);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y - h), 1, h);\n }\n }\n\n break;\n }\n\n case 'logarithmic': {\n const log10Ratio = Math.log10(this.ratio);\n\n const h = innerHeight / (this.logarithmicFrequencies.length - 1);\n\n for (let k = 0; k < frequencyBinCount; k++) {\n if (k === 0) {\n continue;\n }\n\n if ((k !== 1) && ((k % this.plotInterval) !== 0)) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = left + this.timeOffset;\n const y = ((1 - (log10FrequencyRatio / log10Ratio)) * innerHeight) + top;\n\n if (y < top) {\n continue;\n }\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k], this.type, this.analyser?.maxDecibels, this.analyser?.minDecibels);\n\n context.fillStyle = color;\n context.fillRect(x, (y > (top + innerHeight - h) ? (top + innerHeight - h) : y), 1, h);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n context.fillStyle = color;\n context.fillRect(x, (y > (top + innerHeight - h) ? (top + innerHeight - h) : y), 1, h);\n }\n }\n\n break;\n }\n }\n\n // Render time text\n context.fillStyle = textColor;\n context.font = this.createFontString();\n context.textAlign = 'center';\n\n this.numberOfSamples += frequencyBinCount;\n\n this.timeOffset = (this.numberOfSamples * (1 / this.sampleRate)) * (innerWidth / this.duration);\n\n this.imagedata = context.getImageData(0, 0, width, height);\n }\n\n /**\n * This method visualizes spectrogram to SVG.\n * @param {Uint8Array|Float32Array} data This argument is frequency domain data for spectrogram.\n * @override\n */\n protected override visualizeBySVG(data: Uint8Array | Float32Array): void {\n if ((this.svg === null) || !this.isActive) {\n return;\n }\n\n const svg = this.svg;\n\n const width = Number((svg.getAttribute('width') ?? '0'));\n const height = Number((svg.getAttribute('height') ?? '0'));\n const top = this.styles.top ?? 0;\n const bottom = this.styles.bottom ?? 0;\n const left = this.styles.left ?? 30;\n const right = this.styles.right ?? 30;\n const innerWidth = width - (left + right);\n const innerHeight = height - (top + bottom);\n\n const gridColor = this.styles.grid ?? 'none';\n const textColor = this.styles.text ?? 'none';\n const fontSize = Number.parseInt((this.styles.font?.size ?? '13px'), 10);\n\n const frequencyBinCount = data.length;\n const fftSize = 2 * frequencyBinCount;\n\n // Frequency resolution (Sampling rate / FFT size)\n const frequencyResolution = this.sampleRate / fftSize;\n\n const samples = this.duration * this.sampleRate;\n\n if (this.numberOfSamples >= samples) {\n svg.innerHTML = '';\n\n this.timeOffset = 1;\n this.numberOfSamples = 0;\n }\n\n if (svg.innerHTML.length === 0) {\n // Render Graph\n const rectX = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n rectX.setAttribute('x', left.toString(10));\n rectX.setAttribute('y', (top + innerHeight).toString(10));\n rectX.setAttribute('width', innerWidth.toString(10));\n rectX.setAttribute('height', '2');\n rectX.setAttribute('fill', gridColor);\n rectX.setAttribute('stroke', 'none');\n\n const rectY = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n rectY.setAttribute('x', left.toString(10));\n rectY.setAttribute('y', top.toString(10));\n rectY.setAttribute('width', '2');\n rectY.setAttribute('height', innerHeight.toString(10));\n rectY.setAttribute('fill', gridColor);\n rectY.setAttribute('stroke', 'none');\n\n svg.appendChild(rectX);\n svg.appendChild(rectY);\n\n // Render coordinate\n\n // X axis (time)\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n const textInterval = samples / this.timeTextInterval;\n\n for (let k = 0; k < samples; k++) {\n if ((k % textInterval) !== 0) {\n continue;\n }\n\n const x = k * (innerWidth / samples) + left;\n const y = top + innerHeight + fontSize;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n const time = (k / samples) * this.duration;\n\n if ((time !== 0) && (time < 0.0001)) {\n text.textContent = `${(time * 1000).toFixed(1)} msec`;\n } else {\n text.textContent = `${time.toFixed(2)} sec`;\n }\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'start');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n }\n\n svg.appendChild(g);\n\n // Y axis (frequency)\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n for (let k = 0; k <= length; k++) {\n if ((k % this.linearFrequencyTextInterval) !== 0) {\n continue;\n }\n\n const x = left;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const frequency = k * frequencyResolution;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n text.textContent = `${Math.trunc(frequency)} Hz`;\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n }\n\n svg.appendChild(g);\n\n break;\n }\n\n case 'logarithmic': {\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n this.logarithmicFrequencies.forEach((frequency: number, index: number) => {\n const x = left;\n const y = ((1 - (index / this.logarithmicFrequencies.length)) * innerHeight) + top;\n\n const text = document.createElementNS(Spectrogram.XMLNS, 'text');\n\n if (frequency >= 1000) {\n text.textContent = `${Math.trunc(frequency / 1000)} kHz`;\n } else {\n text.textContent = `${frequency} Hz`;\n }\n\n text.setAttribute('x', x.toString(10));\n text.setAttribute('y', y.toString(10));\n text.setAttribute('text-anchor', 'end');\n text.setAttribute('stroke', 'none');\n text.setAttribute('fill', textColor);\n text.setAttribute('font-size', fontSize.toString(10));\n\n g.appendChild(text);\n });\n\n svg.appendChild(g);\n\n break;\n }\n }\n }\n\n // Render spectrogram\n switch (this.scale) {\n case 'linear': {\n const length = Math.min(frequencyBinCount, this.renderSize);\n\n const h = Number.parseInt((this.styles.font?.size ?? '13'), 10);\n\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n for (let k = 0; k < length; k++) {\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const x = left + this.timeOffset;\n const y = ((1 - (k / length)) * innerHeight) + top;\n\n const rect = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k], this.type, this.analyser?.maxDecibels, this.analyser?.minDecibels);\n\n rect.setAttribute('fill', color);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n rect.setAttribute('fill', color);\n }\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (y - h).toString(10));\n rect.setAttribute('width', (this.styles.width ? this.styles.width.toString(10) : '1'));\n rect.setAttribute('height', h.toString(10));\n rect.setAttribute('stroke', 'none');\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n\n case 'logarithmic': {\n const g = document.createElementNS(Spectrogram.XMLNS, 'g');\n\n const log10Ratio = Math.log10(this.ratio);\n\n const h = innerHeight / (this.logarithmicFrequencies.length - 1);\n\n for (let k = 0; k < frequencyBinCount; k++) {\n if (k === 0) {\n continue;\n }\n\n if ((k !== 1) && ((k % this.plotInterval) !== 0)) {\n continue;\n }\n\n const frequency = k * frequencyResolution;\n\n if ((frequency < this.minFrequency) || (frequency > this.maxFrequency)) {\n continue;\n }\n\n const frequencyRatio = frequency / this.minFrequency;\n const log10FrequencyRatio = Math.log10(frequencyRatio);\n\n const x = left + this.timeOffset;\n const y = ((1 - (log10FrequencyRatio / log10Ratio)) * innerHeight) + top;\n\n if (y < top) {\n continue;\n }\n\n const rect = document.createElementNS(Spectrogram.XMLNS, 'rect');\n\n if (this.colorFromNumber === null) {\n const color = Spectrogram.numberToJetColor(data[k], this.type, this.analyser?.maxDecibels, this.analyser?.minDecibels);\n\n rect.setAttribute('fill', color);\n } else {\n const color = this.colorFromNumber(data[k]);\n\n rect.setAttribute('fill', color);\n }\n\n rect.setAttribute('x', x.toString(10));\n rect.setAttribute('y', (y > (top + innerHeight - h) ? (top + innerHeight - h) : y).toString(10));\n rect.setAttribute('width', (this.styles.width ? this.styles.width.toString(10) : '1'));\n rect.setAttribute('height', h.toString(10));\n rect.setAttribute('stroke', 'none');\n\n g.appendChild(rect);\n }\n\n svg.appendChild(g);\n\n break;\n }\n }\n\n\n this.numberOfSamples += frequencyBinCount;\n\n this.timeOffset = (this.numberOfSamples * (1 / this.sampleRate)) * (innerWidth / this.duration);\n }\n}\n","import type { Connectable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { Visualizer, VisualizerParams, Color, GraphicsApi, Gradient, Gradients, Shape, Font, GraphicsStyles, SpectrumScale } from './Visualizer';\nimport type { TimeOverviewParams, CurrentTimeStyles, MouseEventTypes, DragMode, DragCallbackFunction } from './TimeOverview';\nimport type { TimeParams } from './Time';\nimport type { FFTParams } from './FFT';\nimport type { SpectrogramParams } from './Spectrogram';\n\nimport { TimeOverview } from './TimeOverview';\nimport { Time } from './Time';\nimport { FFT } from './FFT';\nimport { Spectrogram } from './Spectrogram';\n\nexport type Domain = 'timeoverview' | 'time' | 'fft' | 'spectrogram';\nexport type DataType = 'uint' | 'float'; // unsigned int 8 bit (`Uint8Array`) or float 32 bit (`Float32Array`)\nexport type FFTSize = 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;\n\nexport type {\n Visualizer,\n VisualizerParams,\n Color,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n CurrentTimeStyles,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams\n};\n\nexport type AnalyserParams = {\n fftSize?: FFTSize,\n readonly frequencyBinCount?: number,\n minDecibels?: number,\n maxDecibels?: number,\n smoothingTimeConstant?: number\n};\n\n/**\n * This private class manages 3 private classes (`TimeOverview`, `Time`, `FFT`) for visualizing sound wave.\n */\nexport class Analyser implements Connectable {\n private analysers: [AnalyserNode, AnalyserNode];\n private splitter: ChannelSplitterNode;\n private input: GainNode;\n\n private timeOverviews: [TimeOverview, TimeOverview];\n private times: [Time, Time];\n private ffts: [FFT, FFT];\n private spectrograms: [Spectrogram, Spectrogram];\n\n private timeDomainAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private timeDomainTimerIds: [number | null, number | null] = [null, null];\n private frequencyDomainAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private frequencyDomainTimerIds: [number | null, number | null] = [null, null];\n private spectrogramAnimationIds: [ReturnType<typeof window.requestAnimationFrame> | null, ReturnType<typeof window.requestAnimationFrame> | null] = [null, null];\n private spectrogramTimerIds: [number | null, number | null] = [null, null];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.analysers = [context.createAnalyser(), context.createAnalyser()];\n this.splitter = context.createChannelSplitter(2);\n this.input = context.createGain();\n\n // GainNode (Input) -> ChannelSplitterNode (L / R) -> AnalyserNode\n this.input.connect(this.splitter);\n this.splitter.connect(this.analysers[0], 0, 0);\n this.splitter.connect(this.analysers[1], 1, 0);\n\n this.timeOverviews = [new TimeOverview(context.sampleRate, 0), new TimeOverview(context.sampleRate, 1)];\n this.times = [new Time(context.sampleRate, 0, this.analysers[0]), new Time(context.sampleRate, 1, this.analysers[1])];\n this.ffts = [new FFT(context.sampleRate, 0, this.analysers[0]), new FFT(context.sampleRate, 1, this.analysers[1])];\n this.spectrograms = [new Spectrogram(context.sampleRate, 0, this.analysers[0]), new Spectrogram(context.sampleRate, 1, this.analysers[1])];\n\n // Set default value\n this.analysers.forEach((analyser: AnalyserNode) => {\n analyser.fftSize = 2048;\n analyser.minDecibels = -100;\n analyser.maxDecibels = -30;\n analyser.smoothingTimeConstant = 0.8;\n });\n }\n\n /**\n * This method visualizes sound wave.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', 'spectrogram'.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @param {AudioBuffer} buffer This argument is instance of `AudioBuffer` (If domain is 'timeoverview', this argument is required).\n * @return {Analyser} Return value is for method chain.\n */\n public start(domain: Domain, channelNumber?: ChannelNumber, buffer?: AudioBuffer): Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n this.input.disconnect(this.splitter);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n\n // GainNode (Input) -> AnalyserNode\n this.input.connect(this.analysers[0]);\n\n channel = 0;\n }\n\n switch (domain) {\n case 'timeoverview': {\n if (buffer && (buffer.numberOfChannels > channel)) {\n const data = new Float32Array(buffer.length);\n\n data.set(buffer.getChannelData(channel));\n\n this.timeOverviews[channel].start(data);\n }\n\n break;\n }\n\n case 'time': {\n const interval = this.times[channel].param('interval');\n\n switch (this.times[channel].param('type')) {\n case 'uint': {\n const data = new Uint8Array(this.analysers[channel].fftSize);\n\n this.analysers[channel].getByteTimeDomainData(data);\n this.times[channel].start(data);\n\n break;\n }\n\n case 'float': {\n const data = new Float32Array(this.analysers[channel].fftSize);\n\n this.analysers[channel].getFloatTimeDomainData(data);\n this.times[channel].start(data);\n\n break;\n }\n }\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.timeDomainAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.timeDomainTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n\n case 'fft': {\n const interval = this.ffts[channel].param('interval');\n\n switch (this.ffts[channel].param('type')) {\n case 'uint': {\n const data = new Uint8Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getByteFrequencyData(data);\n this.ffts[channel].start(data);\n\n break;\n }\n\n case 'float': {\n const data = new Float32Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getFloatFrequencyData(data);\n this.ffts[channel].start(data, this.analysers[channel].minDecibels, this.analysers[channel].maxDecibels);\n\n break;\n }\n }\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.frequencyDomainAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.frequencyDomainTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n\n case 'spectrogram': {\n const interval = this.spectrograms[channel].param('interval');\n\n switch (this.spectrograms[channel].param('type')) {\n case 'uint': {\n const data = new Uint8Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getByteFrequencyData(data);\n this.spectrograms[channel].start(data);\n\n break;\n }\n\n case 'float': {\n const data = new Float32Array(this.analysers[channel].frequencyBinCount);\n\n this.analysers[channel].getFloatFrequencyData(data);\n this.spectrograms[channel].start(data);\n\n break;\n }\n }\n\n if (typeof interval === 'number') {\n this.stop(domain, channelNumber);\n\n if (interval < 0) {\n this.spectrogramAnimationIds[channel] = window.requestAnimationFrame(() => {\n this.start(domain, channelNumber);\n });\n } else {\n this.spectrogramTimerIds[channel] = window.setTimeout(() => {\n this.start(domain, channelNumber);\n }, interval);\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method stops visualizer.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', 'spectrogram'.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {Analyser} Return value is for method chain.\n */\n public stop(domain: Domain, channelNumber?: ChannelNumber): Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n switch (domain) {\n case 'time': {\n const interval = this.times[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.timeDomainAnimationIds[channel];\n const timerId = this.timeDomainTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.timeDomainAnimationIds[channel]= null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.timeDomainTimerIds[channel]= null;\n }\n }\n\n break;\n }\n\n case 'fft': {\n const interval = this.ffts[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.frequencyDomainAnimationIds[channel];\n const timerId = this.frequencyDomainTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.frequencyDomainAnimationIds[channel] = null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.frequencyDomainTimerIds[channel] = null;\n }\n }\n\n break;\n }\n\n case 'spectrogram': {\n const interval = this.spectrograms[channel].param('interval');\n\n if (typeof interval === 'number') {\n const animationId = this.spectrogramAnimationIds[channel];\n const timerId = this.spectrogramTimerIds[channel];\n\n if ((interval < 0) && animationId) {\n window.cancelAnimationFrame(animationId);\n\n this.spectrogramAnimationIds[channel] = null;\n } else if (timerId) {\n window.clearTimeout(timerId);\n\n this.spectrogramTimerIds[channel] = null;\n }\n }\n\n break;\n }\n }\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for analyser.\n * This method is overloaded for type interface and type check.\n * @param {keyof AnalyserParams|AnalyserParams} params This argument is string if getter. Otherwise, setter.\n * @return {AnalyserParams[keyof AnalyserParams]|Analyser} Return value is parameter for analyser if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'fftSize'): number;\n public param(params: 'frequencyBinCount'): number;\n public param(params: 'minDecibels'): number;\n public param(params: 'maxDecibels'): number;\n public param(params: 'smoothingTimeConstant'): number;\n public param(params: AnalyserParams): Analyser;\n public param(params: keyof AnalyserParams | AnalyserParams): AnalyserParams[keyof AnalyserParams] | Analyser {\n if (typeof params === 'string') {\n switch (params) {\n case 'fftSize': {\n return this.analysers[0].fftSize;\n }\n\n case 'frequencyBinCount': {\n return this.analysers[0].frequencyBinCount;\n }\n\n case 'minDecibels': {\n return this.analysers[0].minDecibels;\n }\n\n case 'maxDecibels': {\n return this.analysers[0].maxDecibels;\n }\n\n case 'smoothingTimeConstant': {\n return this.analysers[0].smoothingTimeConstant;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'fftSize': {\n this.analysers[0].fftSize = value;\n this.analysers[1].fftSize = value;\n break;\n }\n\n case 'minDecibels': {\n this.analysers[0].minDecibels = value;\n this.analysers[1].minDecibels = value;\n break;\n }\n\n case 'maxDecibels': {\n this.analysers[0].maxDecibels = value;\n this.analysers[1].maxDecibels = value;\n break;\n }\n\n case 'smoothingTimeConstant': {\n this.analysers[0].smoothingTimeConstant = value;\n this.analysers[1].smoothingTimeConstant = value;\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method selects domain for visualization.\n * This method is overloaded for type interface and type check.\n * @param {Domain} domain This argument is one of 'timeoverview', 'time', 'fft', `spectrogram`.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {TimeOverview|Time|FFT|Analyser} Return value is instance of selected `Visualizer` class.\n */\n public domain(domain: 'timeoverview', channelNumber: ChannelNumber): TimeOverview;\n public domain(domain: 'time', channelNumber?: ChannelNumber): Time;\n public domain(domain: 'fft', channelNumber?: ChannelNumber): FFT;\n public domain(domain: 'spectrogram', channelNumber?: ChannelNumber): Spectrogram;\n public domain(domain: Domain, channelNumber?: ChannelNumber): TimeOverview | Time | FFT | Spectrogram | Analyser {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n switch (domain) {\n case 'timeoverview': {\n return this.timeOverviews[channel];\n }\n\n case 'time': {\n return this.times[channel];\n }\n\n case 'fft': {\n return this.ffts[channel];\n }\n\n case 'spectrogram': {\n return this.spectrograms[channel];\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AnalyserNode`.\n * @param {ChannelNumber} channelNumber This argument is channel number (Left: 0, Right: 1 ...).\n * @return {AnalyserNode}\n */\n public get(channelNumber?: ChannelNumber): AnalyserNode | null {\n let channel = channelNumber;\n\n if ((channel === undefined) || (channel === -1)) {\n channel = 0;\n }\n\n return this.analysers[channel];\n }\n\n /** @override */\n public get INPUT(): GainNode {\n return this.input;\n }\n\n /** @override */\n public get OUTPUT(): GainNode {\n return this.input;\n }\n}\n","/**\n * This class is entity for recording frame.\n * Namely, this class has recorded sound data.\n */\nexport class Frame {\n private id: string;\n private dataBlocks: Float32Array[] = [];\n\n /**\n * @param {id} id This argument is frame ID.\n */\n constructor(id: string) {\n this.id = id;\n }\n\n /**\n * This method gets array that contains recorded sound data.\n * @return {Array<Float32Array>}\n */\n public get(): Float32Array[] {\n return this.dataBlocks;\n }\n\n /**\n * This method appends recorded sound data as `Float32Array`.\n * @param {Float32Array} dataBlock This argument is instance of `Float32Array` that has recorded sound data.\n * @return {Frame} Return value is for method chain.\n */\n public append(dataBlock: Float32Array): Frame {\n this.dataBlocks.push(dataBlock);\n return this;\n }\n\n /**\n * This method clears data blocks.\n */\n public clear(): void {\n this.dataBlocks.length = 0;\n }\n\n /**\n * This method determines whether contains recorded sound data.\n * @return {boolean} If frame has recorded data, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.dataBlocks.length > 0;\n }\n\n /** @override */\n public toString(): string {\n return this.id;\n }\n}\n","import type { Frame } from './Frame';\n\n/**\n * This class is entity for recording channel.\n */\nexport class Channel {\n private id: string;\n private frames: Frame[] = [];\n private channelGain = 1;\n\n /**\n * @param {string} id This argument is channel ID.\n */\n constructor(id: string) {\n this.id = id;\n }\n\n /**\n * This method appends instance of `Frame`.\n * @param {Frame} frame This argument is instance of `Frame` as recording frame.\n * @return {Channel} Return value is for method chain.\n */\n public append(frame: Frame): Channel {\n this.frames.push(frame);\n return this;\n }\n\n /**\n * This method gets designated frame or array that contains the all of frames.\n * This method is overloaded for type interface and type check.\n * @param {number} frameNumber This argument is target frame number.\n * @return {Frame|Array<Frame>}\n */\n public get(frameNumber: number): Frame;\n public get(): Frame[];\n public get(frameNumber?: number): Frame | Frame[] {\n if ((typeof frameNumber === 'number') && (frameNumber >= 0) && (frameNumber < this.frames.length)) {\n return this.frames[frameNumber];\n }\n\n return this.frames;\n }\n\n /**\n * This method gets or sets channel gain.\n * This method is overloaded for type interface and type check.\n * @param {number} param This argument is channel gain.\n * @return {number} Return value is channel gain.\n */\n public gain(): number;\n public gain(param: number): void;\n public gain(param?: number): number | void {\n if ((typeof param === 'number') && (param >= 0) && (param <= 1)) {\n this.channelGain = param;\n return;\n }\n\n return this.channelGain;\n }\n\n /**\n * This method gets the number of frames.\n * @return {number}\n */\n public length(): number {\n return this.frames.length;\n }\n\n /** @override */\n public toString(): string {\n return this.id;\n }\n}\n","import type { Inputs } from '../../worklet';\n\nimport { AudioWorkletProcessor } from '../../worklet';\n\nexport type RecorderProcessorMessageEventData = {\n inputs: Inputs\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method (sends input audio data to main thread) for recording audio.\n */\nexport class RecorderProcessor extends AudioWorkletProcessor {\n public static readonly BUFFER_SIZE = 128 as const;\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs): boolean {\n if ((inputs.length === 0) || (inputs[0].length === 0)) {\n return true;\n }\n\n const message: RecorderProcessorMessageEventData = { inputs };\n\n this.port.postMessage(message);\n\n return true;\n }\n}\n","import type { Connectable } from '../../interfaces';\nimport type { ChannelNumber } from '../../types';\nimport type { RecorderProcessorMessageEventData } from './RecorderProcessor';\n\nimport { Frame } from './Frame';\nimport { Channel } from './Channel';\nimport { RecorderProcessor } from './RecorderProcessor';\n\nexport type RecordType = 1 | 2; // Monaural | Stereo\nexport type QuantizationBit = 8 | 16;\nexport type WaveExportType = 'base64' | 'dataURL' | 'blob' | 'objectURL';\n\nexport type {\n Frame,\n Channel,\n RecorderProcessorMessageEventData\n};\n\nexport type RecorderParams = {\n '0'?: number,\n '1'?: number\n};\n\nexport { RecorderProcessor };\n\n/**\n * This private class is for multi track recording.\n */\nexport class Recorder implements Connectable {\n private processor: AudioWorkletNode;\n private sampleRate: number;\n private channels: Channel[] = [];\n private activeTrack = -1; // There is not any active track in case of -1\n private paused = true; // for preventing from duplicate `onaudioprocess` event (`start` method)\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.processor = new AudioWorkletNode(context, RecorderProcessor.name);\n this.sampleRate = context.sampleRate;\n\n this.processor.port.onmessage = (event: MessageEvent<RecorderProcessorMessageEventData>) => {\n if (this.activeTrack === -1) {\n return;\n }\n\n if (event.data.inputs.length === 0) {\n return;\n }\n\n const inputs = event.data.inputs[0];\n\n if (inputs.length === 0) {\n return;\n }\n\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\n\n if (inputs.length === 1) {\n const inputLs = inputs[0];\n const gainL = this.channels[0].gain();\n const frameL = this.channels[0].get(this.activeTrack);\n const recordedLs = new Float32Array(bufferSize);\n\n for (let i = 0; i < bufferSize; i++) {\n recordedLs[i] = gainL * inputLs[i];\n }\n\n frameL?.append(recordedLs);\n\n return;\n }\n\n const inputLs = inputs[0];\n const inputRs = inputs[1];\n\n const gainL = this.channels[0].gain();\n const gainR = this.channels[1].gain();\n\n const frameL = this.channels[0].get(this.activeTrack);\n const frameR = this.channels[1].get(this.activeTrack);\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 frameL?.append(recordedLs);\n frameR?.append(recordedRs);\n };\n }\n\n /**\n * This method sets the max number of track.\n * @param {RecordType} numberOfChannels This argument is the number of channels (not used currently).\n * @param {number} numberOfTracks This argument is the max number of tracks.\n * @return {Recorder} Return value is for method chain.\n */\n public setup(numberOfChannels: RecordType, numberOfTracks: number): Recorder {\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 < numberOfTracks; i++) {\n channel.append(new Frame(i.toString(10)));\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 * If there is not designated track number, active track number is -1.\n * @return {Recorder} Return value is for method chain.\n */\n public ready(trackNumber: number): Recorder {\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 sound recording. If there is not any active track, this method stops `onaudioprocess` event handler.\n * @return {Recorder} Return value is for method chain.\n */\n public start(): Recorder {\n if ((this.activeTrack === -1) || !this.paused) {\n return this;\n }\n\n this.paused = false;\n\n return this;\n }\n\n /**\n * This method turns off active track, and stops `onaudioprocess` event handler.\n * @return {Recorder} Return value is for method chain.\n */\n public stop(): Recorder {\n this.activeTrack = -1; // Flag becomes inactive\n this.paused = true;\n\n this.processor.disconnect(0);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for recorder.\n * This method is overloaded for type interface and type check.\n * @param {keyof RecorderParams|RecorderParams} params This argument is string if getter. Otherwise, setter.\n * @return {RecorderParams[keyof RecorderParams]|Recorder} Return value is parameter for recorder if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: '0' | '1'): number;\n public param(params: RecorderParams): Recorder;\n public param(params: keyof RecorderParams | RecorderParams): RecorderParams[keyof RecorderParams] | Recorder {\n if (typeof params === 'string') {\n switch (params) {\n case '0': {\n if (this.channels[0]) {\n return this.channels[0].gain();\n }\n\n break;\n }\n\n case '1': {\n if (this.channels[1]) {\n return this.channels[1].gain();\n }\n\n break;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case '0': {\n if (this.channels[0] && (typeof value === 'number')) {\n this.channels[0].gain(value);\n }\n\n break;\n }\n\n case '1': {\n if (this.channels[1] && (typeof value === 'number')) {\n this.channels[1].gain(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method determines whether active track exists.\n * @return {number} Return value is active track number.\n */\n public get(): number {\n return this.activeTrack;\n }\n\n /**\n * This method clears record track.\n * @param {number} trackNumber This argument is track for clearing. If this argument is -1, target is the all of tracks.\n * @return {Recorder} Return value is for method chain.\n */\n public clear(trackNumber: number): Recorder {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n if (trackNumber === -1) {\n for (const channel of this.channels) {\n const frames = channel.get();\n\n for (const frame of frames) {\n frame.clear();\n }\n }\n } else {\n if (this.hasTrack(trackNumber)) {\n for (const channel of this.channels) {\n const frame = channel.get(trackNumber);\n\n frame?.clear();\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method creates WAVE file as one of Base64, Data URL, Blob, Object URL.\n * @param {number} trackNumber This argument is track number for mixing. If this argument is -1, target is the all of tracks.\n * @param {RecordType} numberOfChannels This argument is in order to select monaural or stereo.\n * @param {QuantizationBit} qbits This argument is quantization bit for PCM.\n * @param {WaveExportType} type This argument is one of 'base64', 'dataURL', 'blob', 'objectURL'.\n * @return {string|Blob} Return value is one of Base64, Data URL, Blob, Object URL as WAVE file.\n */\n public create(trackNumber: number, numberOfChannels: RecordType, qbits: QuantizationBit, type: WaveExportType): string | Blob {\n // on the way of recording ?\n if (this.activeTrack !== -1) {\n this.stop();\n }\n\n let soundLs: Float32Array | null = null;\n let soundRs: Float32Array | null = null;\n\n if ((trackNumber === -1) && this.has(-1, -1)) {\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 if ((soundLs === null) || (soundRs === null)) {\n return '';\n }\n\n // PCM parameters\n const RATE = this.sampleRate;\n const QBITS = qbits;\n const CHANNELS = numberOfChannels;\n\n // Parameters for WAVE file\n\n // the number of total samples in entire channels\n const SAMPLES = CHANNELS * Math.min(soundLs.length, soundRs.length);\n\n // chunk ID size + chunk data size\n const CHUNK_SIZE = 4 + 4;\n\n // 1 byte * 4 ('W', 'A', 'V', 'E')\n const FORM_TYPE_ID_SIZE = 4;\n\n // 16 bytes (Format Tag size + Channels size + Sample rate size + BPS size + Block size + Bits per sample size)\n // (+ 2 bytes if Non-PCM)\n // (+ 24 bytes if extensible WAVE (ExWAVE))\n const FMT_CHUNK_SIZE = CHUNK_SIZE + 16;\n\n const DATA_CHUNK_SIZE = CHUNK_SIZE + (SAMPLES * (QBITS / 8));\n\n // WAVE file size\n const SIZE = CHUNK_SIZE + FORM_TYPE_ID_SIZE + FMT_CHUNK_SIZE + DATA_CHUNK_SIZE;\n\n // total size - (RIFF chunk ID size + Form type ID size)\n const RIFF_CHUNK_SIZE = SIZE - (4 + 4);\n\n const BPS = RATE * CHANNELS * (QBITS / 8);\n\n const DATA_SIZE = SAMPLES * (QBITS / 8);\n\n let sounds: Uint8Array | Int16Array | null = null;\n\n switch (QBITS) {\n case 8: {\n sounds = new Uint8Array(SAMPLES);\n\n for (let i = 0; i < SAMPLES; i++) {\n // Convert to 8 bits unsigned integer (-1 -> 0, 0 -> 128, 1 -> 255)\n let binary = 0;\n\n if ((i % CHANNELS) === 0) {\n binary = Math.round(((soundLs[Math.trunc(i / CHANNELS)] + 1) / 2) * ((2 ** 8) - 1)); // Left channel\n } else {\n binary = Math.round(((soundRs[Math.trunc(i / CHANNELS)] + 1) / 2) * ((2 ** 8) - 1)); // Right channel\n }\n\n // for preventing from clipping\n if (binary > ((2 ** 8) - 1)) { binary = ((2 ** 8) - 1); }\n if (binary < ((2 ** 0) - 1)) { binary = ((2 ** 0) - 1); }\n\n sounds[i] = binary;\n }\n\n break;\n }\n\n case 16: {\n sounds = new Int16Array(SAMPLES);\n\n for (let i = 0; i < SAMPLES; i++) {\n // Convert to 16 bits signed integer (-1 -> -32768, 0 -> 0, 1 -> 32767)\n let binary = 0;\n\n if ((i % CHANNELS) === 0) {\n binary = Math.round(soundLs[Math.trunc(i / CHANNELS)] * (2 ** 15)); // Left channel\n } else {\n binary = Math.round(soundRs[Math.trunc(i / CHANNELS)] * (2 ** 15)); // Right channel\n }\n\n // for preventing from clipping\n if (binary > (+(2 ** 15) - 1)) { binary = +(2 ** 15) - 1; }\n if (binary < (-(2 ** 15) - 0)) { binary = -(2 ** 15) - 0; }\n\n sounds[i] = binary;\n }\n\n break;\n }\n }\n\n if (sounds === null) {\n return '';\n }\n\n // Byte order is little endian\n const wave = new Uint8Array(SIZE);\n\n // RIFF chunk\n\n // chunk ID\n wave[0] = 0x52; // 'R'\n wave[1] = 0x49; // 'I'\n wave[2] = 0x46; // 'F'\n wave[3] = 0x46; // 'F'\n\n // chunk data size\n wave[4] = (RIFF_CHUNK_SIZE >> 0) & 0xFF;\n wave[5] = (RIFF_CHUNK_SIZE >> 8) & 0xFF;\n wave[6] = (RIFF_CHUNK_SIZE >> 16) & 0xFF;\n wave[7] = (RIFF_CHUNK_SIZE >> 24) & 0xFF;\n\n // Form type ID\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\n // chunk ID\n wave[12] = 0x66; // 'f'\n wave[13] = 0x6D; // 'm'\n wave[14] = 0x74; // 't'\n wave[15] = 0x20; // ' '\n\n // chunk data size\n wave[16] = 16;\n wave[17] = 0;\n wave[18] = 0;\n wave[19] = 0;\n\n // Format Tag\n // 1: PCM (Pulse Code Modulation)\n // 2: MS ADPCM (Adaptive Differential PCM)\n // 6: A-law\n // 7: μ-law\n // ... etc\n wave[20] = 1;\n wave[21] = 0;\n\n // Channels\n // 1: Monaural\n // 2: Stereo\n wave[22] = CHANNELS;\n wave[23] = 0;\n\n // 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 // (Average) Bytes 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 // Block size\n wave[32] = CHANNELS * (QBITS / 8);\n wave[33] = 0;\n\n // Bits per sample\n wave[34] = QBITS;\n wave[35] = 0;\n\n // data chunk\n\n // chunk ID\n wave[36] = 0x64; // 'd'\n wave[37] = 0x61; // 'a'\n wave[38] = 0x74; // 't\n wave[39] = 0x61; // 'a'\n\n // chunk data size\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 // PCM data\n for (let i = 0; i < SAMPLES; i++) {\n const offset = SIZE - DATA_SIZE;\n\n switch (QBITS) {\n case 8: {\n wave[offset + i] = sounds[i];\n break;\n }\n\n case 16: {\n wave[offset + (2 * i) + 0] = ((sounds[i] >> 0) & 0x00FF);\n wave[offset + (2 * i) + 1] = ((sounds[i] >> 8) & 0x00FF);\n break;\n }\n }\n }\n\n // Create WAVE file (as one of Base64, Data URL, Blob, Object URL)\n switch (type) {\n case 'base64' :\n case 'dataURL': {\n const base64 = window.btoa(Array.from(wave).map((d: number) => String.fromCodePoint(d)).join(''));\n\n if (type === 'base64') {\n return base64;\n }\n\n return `data:audio/wav;base64,${base64}`;\n }\n\n case 'blob' :\n case 'objectURL': {\n const blob = new Blob([wave], { type: 'audio/wav' });\n\n if (type === 'blob') {\n return blob;\n }\n\n return window.URL.createObjectURL(blob);\n }\n }\n }\n\n /**\n * This method determines whether track has recorded data.\n * @param {ChanneNumber} channelNumber This argument is target channel number (if this argument is -1, target is the all of channels).\n * @param {number} trackNumber This argument is target track number (if this argument is -1, target is the all of tracks).\n * @return {boolean} If there is track that has recorded data at least, this method returns `true`. Otherwise this value is `false`.\n */\n public has(channelNumber: ChannelNumber, trackNumber: number): boolean {\n if (!this.hasChannel(channelNumber)) {\n return this.channels.some((channel: Channel) => {\n const frames = channel.get();\n\n return frames.some((frame: Frame) => frame.has());\n });\n }\n\n const frames = this.channels[channelNumber].get();\n\n if (!this.hasTrack(trackNumber)) {\n return frames.some((frame: Frame) => frame.has());\n }\n\n const frame = this.channels[channelNumber].get(trackNumber);\n\n return frame?.has() ?? false;\n }\n\n /**\n * This method determines whether designated channel number is valid.\n * @param {ChanneNumber} channelNumber This argument is channel number for validation.\n * @return {boolean} If designated channel is valid, this value is `true`. Otherwise, this value is `false`.\n */\n public hasChannel(channelNumber: ChannelNumber): boolean {\n return (channelNumber >= 0) && (channelNumber < this.channels.length);\n }\n\n /**\n * This method determines whether designated track number is valid.\n * @param {number} trackNumber This argument is track number for validation.\n * @return {boolean} If designated track is valid, this value is `true`. Otherwise, this value is `false`.\n */\n public hasTrack(trackNumber: number): boolean {\n return (trackNumber >= 0) && this.channels.every((channel: Channel) => trackNumber < channel.length());\n }\n\n /** @override */\n public get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public get OUTPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /**\n * This method flats recorded sound data (data block of `Float32Array`) that track contains.\n * @param {ChanneNumber} channelNumber This argument is channel number for mixing.\n * @param {number} trackNumber This argument is track number.\n * @return {Float32Array} Return value is instance of `Float32Array` that contains flatten sound data.\n */\n private flatTrack(channelNumber: ChannelNumber, trackNumber: number): Float32Array | null {\n if (!this.hasChannel(channelNumber) || !this.hasTrack(trackNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const frame = channel.get(trackNumber);\n\n if (frame === null) {\n return null;\n }\n\n const dataBlocks = frame.get();\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\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 sound data that plural track contains.\n * @param {ChannelNumber} channelNumber This argument is channel number for mixing.\n * @return {Float32Array} Return value is instance of `Float32Array` that contains synthesized sound data.\n */\n private mixTrack(channelNumber: ChannelNumber): Float32Array | null {\n if (!this.hasChannel(channelNumber)) {\n return null;\n }\n\n const channel = this.channels[channelNumber];\n const frames = channel.get();\n const bufferSize = RecorderProcessor.BUFFER_SIZE;\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 frame\n for (const frame of frames) {\n const dataBlocks = frame.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 currentFrame = 0, len = frames.length; currentFrame < len; currentFrame++) {\n const frame = frames[currentFrame];\n const dataBlocks = frame.get();\n const dataBlock = dataBlocks[currentBlock];\n\n if (dataBlock && ((index >= 0) && (index <= dataBlock.length))) {\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 data block of `Float32Array`\n currentBlock++;\n index = 0;\n }\n }\n }\n}\n","import type { Connectable, Statable } from '../../interfaces';\n\n/**\n * This class is superclass for effector classes.\n * Also, this class is used for implementing custom effector.\n */\nexport abstract class Effector implements Connectable, Statable {\n protected context: AudioContext;\n protected input: GainNode;\n protected output: GainNode;\n\n protected lfo: OscillatorNode;\n protected depth: GainNode;\n protected rate: AudioParam;\n\n protected isActive = true;\n protected paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n\n // for connecting external modules\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 }\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 */\n public start(startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.lfo.start(startTime ?? this.context.currentTime);\n this.paused = false;\n }\n\n /**\n * This method stops LFO, then creates 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 */\n public stop(stopTime?: number, releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n // Store parameters\n const type = this.lfo.type;\n const rate = this.lfo.frequency.value;\n\n // Destroy instance of `OscillatorNode`\n this.lfo.stop((stopTime ?? this.context.currentTime) + (releaseTime ?? 0));\n\n // Create instance of `OscillatorNode` again\n this.lfo = this.context.createOscillator();\n\n // Restore parameters\n this.lfo.type = type;\n this.lfo.frequency.value = rate;\n\n this.rate = this.lfo.frequency;\n\n this.paused = true;\n }\n\n /**\n * This method connects `AudioNode`s for effector.\n * @return {GainNode} Return value is for `connect` method chain.\n */\n public abstract connect(): GainNode;\n\n /**\n * This method gets effector's parameters as associative array.\n */\n public abstract params(): void;\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * This method gets effector state. If returns `true`, effector is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates effector.\n * @return {Effector} Return value is for method chain.\n */\n public activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Start LFO\n this.start(0);\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method deactivates effector.\n * @return {Effector} Return value is for method chain.\n */\n public deactivate() {\n // Stop LFO\n this.stop(0);\n\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * Connector for input.\n */\n public get INPUT(): GainNode {\n return this.input;\n }\n\n /**\n * Connector for output.\n */\n public get OUTPUT(): GainNode {\n return this.output;\n }\n}\n","import { Effector } from './Effector';\n\nexport type AutopannerParams = {\n state?: boolean,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Autopanner.\n */\nexport class Autopanner extends Effector {\n private panner: StereoPannerNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.panner = this.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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect again\n this.lfo.connect(this.depth);\n this.depth.connect(this.panner.pan);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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.output;\n }\n\n /**\n * This method gets or sets parameters for autopanner effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof AutopannerParams|AutopannerParams} params This argument is string if getter. Otherwise, setter.\n * @return {AutopannerParams[keyof AutopannerParams]|Autopanner} Return value is parameter for autopanner effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: AutopannerParams): Autopanner;\n public param(params: keyof AutopannerParams | AutopannerParams): AutopannerParams[keyof AutopannerParams] | Autopanner {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<AutopannerParams> {\n return {\n state: this.isActive,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type BitCrusherParams = {\n state?: boolean,\n bits?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for BitCrusher.\n */\nexport class BitCrusher extends Effector {\n private shaper: WaveShaperNode;\n private inputShaper: WaveShaperNode;\n private outputShaper: WaveShaperNode;\n private inputLevel: GainNode;\n private outputLevel: GainNode;\n private bitsInput: ConstantSourceNode;\n private bitsGain: GainNode;\n\n private bits = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = this.context.createWaveShaper();\n this.inputShaper = this.context.createWaveShaper();\n this.outputShaper = this.context.createWaveShaper();\n\n this.inputLevel = this.context.createGain();\n this.outputLevel = this.context.createGain();\n\n this.bitsInput = this.context.createConstantSource();\n this.bitsGain = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1023);\n\n for (let i = 0; i < 512; i++) {\n const v = (((i / 512) * 128) | 0) / 128;\n\n curve[511 + i] = v;\n curve[511 - i] = -v;\n }\n\n const inputCurve = new Float32Array(10);\n const outputCurve = new Float32Array(10);\n\n for (let i = 0, d = 64; i < 6; i++, d *= 0.5) {\n inputCurve[0 + i] = 1 / 64;\n inputCurve[4 + i] = 1 / d;\n\n outputCurve[0 + i] = 64;\n outputCurve[4 + i] = d;\n }\n\n this.shaper.curve = curve;\n this.shaper.oversample = '4x';\n this.inputShaper.curve = inputCurve;\n this.outputShaper.curve = outputCurve;\n\n this.inputLevel.gain.value = 0;\n this.outputLevel.gain.value = 0;\n\n this.bitsInput.offset.value = this.bits;\n this.bitsGain.gain.value = 1 / 8;\n\n // `BitCrusher` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.bitsInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.bitsInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.bitsInput = this.context.createConstantSource();\n\n // Restore parameters\n this.bitsInput.offset.value = this.bits;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.shaper.disconnect(0);\n this.inputShaper.disconnect(0);\n this.outputShaper.disconnect(0);\n this.inputLevel.disconnect(0);\n this.outputLevel.disconnect(0);\n this.bitsInput.disconnect(0);\n this.bitsGain.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Input Gain) -> WaveShaperNode (Bit Crusher) -> GainNode (Output Gain) -> GainNode (Output)\n this.input.connect(this.inputLevel);\n this.inputLevel.connect(this.shaper);\n this.shaper.connect(this.outputLevel);\n this.outputLevel.connect(this.output);\n\n // ConstantSourceNode (Input as Bit Crusher) -> GainNode (Bit Crusher Gain)\n this.bitsInput.connect(this.bitsGain);\n\n // GainNode (Bit Crusher Gain) -> WaveShaperNode (Input Envelope Follower) -> AudioParam (gain as input)\n this.bitsGain.connect(this.inputShaper);\n this.inputShaper.connect(this.inputLevel.gain);\n\n // GainNode (Bit Crusher Gain) -> WaveShaperNode (Output Envelope Follower) -> AudioParam (gain as output)\n this.bitsGain.connect(this.outputShaper);\n this.outputShaper.connect(this.outputLevel.gain);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for bit crusher effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof BitCrusherParams|BitCrusherParams} params This argument is string if getter. Otherwise, setter.\n * @return {BitCrusherParams[keyof BitCrusherParams]|BitCrusher} Return value is parameter for bit crusher effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'bits'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: BitCrusherParams): BitCrusher;\n public param(params: keyof BitCrusherParams | BitCrusherParams): BitCrusherParams[keyof BitCrusherParams] | BitCrusher {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'bits': {\n return this.bits;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'bits': {\n if (typeof value === 'number') {\n this.bits = value;\n this.bitsInput.offset.value = this.bits;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<BitCrusherParams> {\n return {\n state : this.isActive,\n bits : this.bits,\n oversample: this.shaper.oversample\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type ChorusParams = {\n state?: boolean,\n time?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Chorus.\n */\nexport class Chorus extends Effector {\n private delay: DelayNode;\n private tone: BiquadFilterNode;\n private dry: GainNode;\n private wet: GainNode;\n private feedback: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.delay = context.createDelay();\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.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = 'lowpass';\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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode's again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for chorus effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof ChorusParams|ChorusParams} params This argument is string if getter. Otherwise, setter.\n * @return {ChorusParams[keyof ChorusParams]|Chorus} Return value is parameter for chorus effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: ChorusParams): Chorus;\n public param(params: keyof ChorusParams | ChorusParams): ChorusParams[keyof ChorusParams] | Chorus {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.delay.delayTime.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<ChorusParams> {\n return {\n state : this.isActive,\n time : this.delay.delayTime.value,\n depth : this.depthRate,\n rate : this.rate.value,\n mix : this.wet.gain.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}\n","import { Effector } from './Effector';\n\nexport type CompressorParams = {\n state?: boolean,\n threshold?: number,\n knee?: number,\n ratio?: number,\n attack?: number,\n release?: number\n};\n\n/**\n * Effector's subclass for Compressor.\n */\nexport class Compressor extends Effector {\n private compressor: DynamicsCompressorNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.compressor = context.createDynamicsCompressor();\n\n // Initialize parameters\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.activate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Compressor) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for compressor.\n * This method is overloaded for type interface and type check.\n * @param {keyof CompressorParams|CompressorParams} params This argument is string if getter. Otherwise, setter.\n * @return {CompressorParams[keyof CompressorParams]|Compressor} Return value is parameter for compressor if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'threshold'): number;\n public param(params: 'knee'): number;\n public param(params: 'ratio'): number;\n public param(params: 'attack'): number;\n public param(params: 'release'): number;\n public param(params: CompressorParams): Compressor;\n public param(params: keyof CompressorParams | CompressorParams): CompressorParams[keyof CompressorParams] | Compressor {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'threshold': {\n return this.compressor.threshold.value;\n }\n\n case 'knee': {\n return this.compressor.knee.value;\n }\n\n case 'ratio': {\n return this.compressor.ratio.value;\n }\n\n case 'attack': {\n return this.compressor.attack.value;\n }\n\n case 'release': {\n return this.compressor.release.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.compressor.threshold.value = value;\n }\n\n break;\n }\n\n case 'knee': {\n if (typeof value === 'number') {\n this.compressor.knee.value = value;\n }\n\n break;\n }\n\n case 'ratio': {\n if (typeof value === 'number') {\n this.compressor.ratio.value = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.compressor.attack.value = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.compressor.release.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<CompressorParams> {\n return {\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}\n","import { Effector } from './Effector';\n\nexport type DelayParams = {\n state?: boolean,\n time?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Delay.\n */\nexport class Delay extends Effector {\n public static MAX_DELAY_TIME = 5; // Max delay time is 5000 [ms]\n\n private delay: DelayNode;\n private dry: GainNode;\n private wet: GainNode;\n private tone: BiquadFilterNode;\n private feedback: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\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 = 'lowpass';\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for delay effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof DelayParams|DelayParams} params This argument is string if getter. Otherwise, setter.\n * @return {DelayParams[keyof DelayParams]|Delay} Return value is parameter for delay effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: DelayParams): Delay;\n public param(params: keyof DelayParams | DelayParams): DelayParams[keyof DelayParams] | Delay {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<DelayParams> {\n return {\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}\n","import type { Statable } from '../../interfaces';\n\nexport type EnvelopeGeneratorParams = {\n state?: boolean,\n attack?: number,\n decay?: number,\n sustain?: number,\n release?: number\n};\n\n/**\n * This private class is for Envelope Generator.\n */\nexport class EnvelopeGenerator implements Statable {\n public static MIN_GAIN = 1e-3;\n\n private context: AudioContext;\n private generators: GainNode[] = [];\n private activeIndexes: number[] = [];\n private activeCounter = 0;\n\n private attack = 0.01;\n private decay = 0.3;\n private sustain = 0.5;\n private release = 1.0;\n\n private isActive = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n }\n\n /**\n * This method connects instance of `AudioNode`.\n * @param {number} index This argument is in order to select instance of `GainNode` that is Envelope Generator.\n * @param {AudioNode} input This argument is instance of `AudioNode` as input.\n * @param {AudioNode} output This argument is instance of `AudioNode` as output.\n */\n public ready(index: number, input: AudioNode | null, output: AudioNode | null): void {\n if (input && output && this.generators[index]) {\n input.connect(this.generators[index]);\n this.generators[index].connect(output);\n } else if (input && (output === null) && this.generators[index]) {\n input.connect(this.generators[index]);\n } else if ((input === null) && output && this.generators[index]) {\n this.generators[index].connect(output);\n }\n\n this.activeIndexes[index] = index;\n this.activeCounter++;\n }\n\n /**\n * This method changes gain (Attack -> Decay -> Sustain).\n * @param {number} startTime This argument is start time of Attack.\n */\n public start(startTime: number): void {\n // Attack -> Decay -> Sustain\n const t0 = startTime;\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 if (!this.isActive) {\n this.generators[activeIndex].gain.value = 1;\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\n /**\n * This method changes gain (Attack or Decay or Sustain -> Release).\n * @param {number} stopTime This argument is start time of Release.\n * @param {boolean} useCurve This argument is to use different methods. The default value is `false`.\n */\n public stop(stopTime: number, useCurve?: boolean): void {\n const s = stopTime - this.release;\n\n // Sustain -> Release\n const t3 = s >= this.context.currentTime ? s : this.context.currentTime;\n const t4 = this.release;\n\n for (const activeIndex of this.activeIndexes) {\n if (activeIndex === undefined) {\n continue;\n }\n\n if (!this.isActive) {\n this.generators[activeIndex].gain.value = 0;\n continue;\n }\n\n // in case of mouseup on the way of Decay\n if (typeof this.generators[activeIndex].gain.cancelAndHoldAtTime === 'function') {\n this.generators[activeIndex].gain.cancelAndHoldAtTime(t3);\n } else {\n const value = this.generators[activeIndex].gain.value;\n\n this.generators[activeIndex].gain.cancelScheduledValues(t3);\n this.generators[activeIndex].gain.setValueAtTime(value, t3);\n }\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\n /**\n * This method gets or sets parameters for envelope generator.\n * This method is overloaded for type interface and type check.\n * @param {keyof EnvelopeGeneratorParams|EnvelopeGeneratorParams} params This argument is string if getter. Otherwise, setter.\n * @return {EnvelopeGeneratorParams[keyof EnvelopeGeneratorParams]|EnvelopeGenerator} Return value is parameter for envelope generator if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'attack'): number;\n public param(params: 'decay'): number;\n public param(params: 'sustain'): number;\n public param(params: 'release'): number;\n public param(params: EnvelopeGeneratorParams): EnvelopeGenerator;\n public param(params: keyof EnvelopeGeneratorParams | EnvelopeGeneratorParams): EnvelopeGeneratorParams[keyof EnvelopeGeneratorParams] | EnvelopeGenerator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'attack': {\n return this.attack;\n }\n\n case 'decay': {\n return this.decay;\n }\n\n case 'sustain': {\n return this.sustain;\n }\n\n case 'release': {\n return this.release;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.attack = value;\n }\n\n break;\n }\n\n case 'decay': {\n if (typeof value === 'number') {\n this.decay = value;\n }\n\n break;\n }\n\n case 'sustain': {\n if (typeof value === 'number') {\n this.sustain = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.release = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is index of array that contains instance of `GainNode` for Envelope Generator.\n * @return {GainNode} This is returned as instance of `GainNode` for Envelope Generator.\n */\n public getGenerator(index: number): GainNode | null {\n if ((index >= 0) && (index < this.generators.length)) {\n return this.generators[index];\n }\n\n return null;\n }\n\n /**\n * This method sets instance of `GainNode` for Envelope Generator.\n * @param {number} index This argument is index of array that contains instance of `GainNode` for Envelope Generator.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n public setGenerator(index: number): void {\n this.generators[index] = this.context.createGain();\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 public paused(): boolean {\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 return false;\n }\n\n /**\n * This method clears variables for managing instance of `GainNode`.\n * @param {boolean} disconnected This argument is in order to determine whether disconnect `AudioNode`.\n * @return {EnvelopeGenerator} This is returned for method chain.\n */\n public clear(disconnected: boolean): void {\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 (disconnected) {\n generator.disconnect(0);\n }\n }\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {EnvelopeGeneratorParams}\n */\n public params(): Required<EnvelopeGeneratorParams> {\n return {\n state : this.isActive,\n attack : this.attack,\n decay : this.decay,\n sustain: this.sustain,\n release: this.release\n };\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * This method gets envelope generator state. If returns `true`, envelope generator is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates envelope generator.\n * @return {EnvelopeGenerator} Return value is for method chain.\n */\n public activate(): EnvelopeGenerator {\n this.isActive = true;\n return this;\n }\n\n /**\n * This method deactivates envelope generator.\n * @return {EnvelopeGenerator} Return value is for method chain.\n */\n public deactivate(): EnvelopeGenerator {\n this.isActive = false;\n return this;\n }\n}\n","import { Effector } from './Effector';\n\nexport type EqualizerParams = {\n state?: boolean,\n bass?: number,\n middle?: number,\n treble?: number,\n presence?: number\n};\n\n/**\n * Effector's subclass for Equalizer.\n */\nexport class Equalizer extends Effector {\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n private presence: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n **/\n constructor(context: AudioContext) {\n super(context);\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n this.presence = context.createBiquadFilter();\n\n // Initialize parameters\n\n // Set filter type\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n this.presence.type = 'highshelf';\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; // Not used\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: Peaking) -> BiquadFilterNode (Presence: High-shelving) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof EqualizerParams|EqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {EqualizerParams[keyof EqualizerParams]|Equalizer} Return value is parameter for equalizer if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'presence'): number;\n public param(params: EqualizerParams): Equalizer;\n public param(params: keyof EqualizerParams | EqualizerParams): EqualizerParams[keyof EqualizerParams] | Equalizer {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'presence': {\n return this.presence.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'presence': {\n if (typeof value === 'number') {\n this.presence.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<EqualizerParams> {\n return {\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}\n","import { Effector } from './Effector';\n\nexport type FilterParams = {\n state?: boolean,\n type?: BiquadFilterType,\n frequency?: number,\n Q?: number,\n gain?: number,\n range?: number,\n attack?: number,\n decay?: number,\n sustain?: number,\n release?: number\n};\n\n/**\n * Effector's subclass for Filter.\n */\nexport class Filter extends Effector {\n private filter: BiquadFilterNode;\n\n private maxFrequency: number;\n private range = 0.1; // 10% -> between `maxFrequency * 0.1` and `maxFrequency`\n\n private attack = 0.01;\n private decay = 0.3;\n private sustain = 1.0;\n private release = 1.0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.filter = context.createBiquadFilter();\n\n // Initialize parameters\n this.filter.type = 'lowpass';\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\n // `Filter` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(startTime?: number): void {\n if (!this.isActive) {\n return;\n }\n\n const t0 = startTime ?? this.context.currentTime;\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 /** @override */\n public override stop(stopTime?: number): void {\n if (!this.isActive) {\n return;\n }\n\n const t3 = stopTime ?? this.context.currentTime;\n const t4 = this.release;\n\n const minFrequnecy = this.maxFrequency * this.range;\n\n // Envelope Generator for filter\n if (typeof this.filter.frequency.cancelAndHoldAtTime === 'function') {\n this.filter.frequency.cancelAndHoldAtTime(t3);\n } else {\n const value = this.filter.frequency.value;\n\n this.filter.frequency.cancelScheduledValues(t3);\n this.filter.frequency.setValueAtTime(value, t3);\n }\n\n this.filter.frequency.setTargetAtTime(minFrequnecy, t3, t4); // Sustain -> Release\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Filter) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for filter effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FilterParams|FilterParams} params This argument is string if getter. Otherwise, setter.\n * @return {FilterParams[keyof FilterParams]|Filter} Return value is parameter for filter effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): BiquadFilterType;\n public param(params: 'frequency'): number;\n public param(params: 'Q'): number;\n public param(params: 'gain'): number;\n public param(params: 'range'): number;\n public param(params: 'attack'): number;\n public param(params: 'decay'): number;\n public param(params: 'sustain'): number;\n public param(params: 'release'): number;\n public param(params: FilterParams): Filter;\n public param(params: keyof FilterParams | FilterParams): FilterParams[keyof FilterParams] | Filter {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.filter.type;\n }\n\n case 'frequency': {\n return this.filter.frequency.value;\n }\n\n case 'Q': {\n return this.filter.Q.value;\n }\n\n case 'gain': {\n return this.filter.gain.value;\n }\n\n case 'range': {\n return this.range;\n }\n\n case 'attack': {\n return this.attack;\n }\n\n case 'decay': {\n return this.decay;\n }\n\n case 'sustain': {\n return this.sustain;\n }\n\n case 'release': {\n return this.release;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.filter.type = value;\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n this.filter.frequency.value = value;\n this.maxFrequency = value;\n }\n\n break;\n }\n\n case 'Q': {\n if (typeof value === 'number') {\n this.filter.Q.value = value;\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.filter.gain.value = value;\n }\n\n break;\n }\n\n case 'range': {\n if (typeof value === 'number') {\n this.range = value;\n }\n\n break;\n }\n\n case 'attack': {\n if (typeof value === 'number') {\n this.attack = value;\n }\n\n break;\n }\n\n case 'decay': {\n if (typeof value === 'number') {\n this.decay = value;\n }\n\n break;\n }\n\n case 'sustain': {\n if (typeof value === 'number') {\n this.sustain = value;\n }\n\n break;\n }\n\n case 'release': {\n if (typeof value === 'number') {\n this.release = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FilterParams> {\n return {\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\n /** @override */\n public override activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /** @override */\n public override deactivate() {\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n}\n","import { Effector } from './Effector';\n\nexport type FlangerParams = {\n state?: boolean,\n time?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number,\n tone?: number,\n feedback?: number\n};\n\n/**\n * Effector's subclass for Flanger.\n */\nexport class Flanger extends Effector {\n private delay: DelayNode;\n private tone: BiquadFilterNode;\n private dry: GainNode;\n private wet: GainNode;\n private feedback: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.delay = context.createDelay();\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.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n this.tone.type = 'lowpass';\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.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.delay.delayTime);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Delay) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for flanger effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FlangerParams|FlangerParams} params This argument is string if getter. Otherwise, setter.\n * @return {FlangerParams[keyof FlangerParams]|Flanger} Return value is parameter for flanger effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: 'feedback'): number;\n public param(params: FlangerParams): Flanger;\n public param(params: keyof FlangerParams | FlangerParams): FlangerParams[keyof FlangerParams] | Flanger {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n\n case 'feedback': {\n return this.feedback.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n this.depth.gain.value = this.delay.delayTime.value * this.depthRate;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.delay.delayTime.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n\n case 'feedback': {\n if (typeof value === 'number') {\n this.feedback.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FlangerParams> {\n return {\n state : this.isActive,\n time : this.delay.delayTime.value,\n depth : this.depthRate,\n rate : this.rate.value,\n mix : this.wet.gain.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}\n","import { Effector } from './Effector';\n\nexport type FuzzParams = {\n state?: boolean,\n drive?: number,\n level?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for Fuzz.\n */\nexport class Fuzz extends Effector {\n private positiveShaper: WaveShaperNode;\n private negativeShaper: WaveShaperNode;\n private positiveInputGain: GainNode;\n private negativeInputGain: GainNode;\n private positiveOutputGain: GainNode;\n private negativeOutputGain: GainNode;\n private outFilter: BiquadFilterNode;\n private driveInput: ConstantSourceNode;\n private level: GainNode;\n\n private drive = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.positiveShaper = this.context.createWaveShaper();\n this.negativeShaper = this.context.createWaveShaper();\n this.positiveInputGain = this.context.createGain();\n this.negativeInputGain = this.context.createGain();\n this.positiveOutputGain = this.context.createGain();\n this.negativeOutputGain = this.context.createGain();\n\n this.driveInput = this.context.createConstantSource();\n\n this.outFilter = this.context.createBiquadFilter();\n\n this.level = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1024);\n\n for (let i = 0; i < 512; i++) {\n const r = Math.tanh((4 * i) / 512) * 0.5;\n const v = 1 - (i / 512);\n\n curve[512 + i] = r;\n curve[511 - i] = r * (v ** 4);\n }\n\n this.positiveShaper.curve = curve;\n this.negativeShaper.curve = curve;\n\n this.positiveShaper.oversample = '4x';\n this.negativeShaper.oversample = '4x';\n\n this.positiveInputGain.gain.value = 1;\n this.negativeInputGain.gain.value = -1;\n\n this.positiveOutputGain.gain.value = 1;\n this.negativeOutputGain.gain.value = -1;\n\n this.driveInput.offset.value = this.drive;\n\n this.outFilter.type = 'highpass';\n this.outFilter.frequency.value = 80;\n this.outFilter.Q.value = 1;\n this.outFilter.gain.value = 0;\n\n this.level.gain.value = 1;\n\n // `Fuzz` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.driveInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.driveInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.driveInput = this.context.createConstantSource();\n\n // Restore parameters\n this.driveInput.offset.value = this.drive;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.positiveShaper.disconnect(0);\n this.negativeShaper.disconnect(0);\n this.positiveInputGain.disconnect(0);\n this.negativeInputGain.disconnect(0);\n this.positiveOutputGain.disconnect(0);\n this.negativeOutputGain.disconnect(0);\n this.driveInput.disconnect(0);\n this.outFilter.disconnect(0);\n this.level.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Positive Input Gain) -> WaveShaperNode (+Fuzz) -> GainNode (Positive Output Gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.positiveInputGain);\n this.positiveInputGain.connect(this.positiveShaper);\n this.positiveShaper.connect(this.positiveOutputGain);\n this.positiveOutputGain.connect(this.outFilter);\n\n // GainNode (Input) > GainNode (Negative Input Gain) -> WaveShaperNode (-Fuzz) -> GainNode (Negative Output Gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.negativeInputGain);\n this.negativeInputGain.connect(this.negativeShaper);\n this.negativeShaper.connect(this.negativeOutputGain);\n this.negativeOutputGain.connect(this.outFilter);\n\n // ConstantSourceNode (Input as Fuzz) -> AudioParam (gain as negative output gain)\n this.driveInput.connect(this.negativeOutputGain.gain);\n\n // BiquadFilterNode (High-pass) -> GainNode (Fuzz Level) -> GainNode (Output)\n this.outFilter.connect(this.level);\n this.level.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.output;\n }\n\n /**\n * This method gets or sets parameters for fuzz effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FuzzParams|FuzzParams} params This argument is string if getter. Otherwise, setter.\n * @return {FuzzParams[keyof FuzzParams]|Fuzz} Return value is parameter for fuzz effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'drive'): number;\n public param(params: 'level'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: FuzzParams): Fuzz;\n public param(params: keyof FuzzParams | FuzzParams): FuzzParams[keyof FuzzParams] | Fuzz {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'drive': {\n return this.drive;\n }\n\n case 'level': {\n return this.level.gain.value;\n }\n\n case 'oversample': {\n return this.positiveShaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'drive': {\n if (typeof value === 'number') {\n this.drive = value;\n this.driveInput.offset.value = this.drive;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level.gain.value = value;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.positiveShaper.oversample = value;\n this.negativeShaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FuzzParams> {\n return {\n state : this.isActive,\n drive : this.drive,\n level : this.level.gain.value,\n oversample: this.positiveShaper.oversample\n };\n }\n}\n","import type { Position3D } from './Panner';\n\nimport { Effector } from './Effector';\n\nexport type ListenerParams = {\n x?: number,\n y?: number,\n z?: number,\n fx?: number,\n fy?: number,\n fz?: number,\n ux?: number,\n uy?: number,\n uz?: number\n};\n\n/**\n * Effector's subclass for Listener.\n */\nexport class Listener extends Effector {\n private listener: AudioListener;\n\n private positions: Position3D;\n private forwards: Position3D;\n private ups: Position3D;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n // 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 // Initialize parameters\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n this.listener.setOrientation(this.forwards.x, this.forwards.y, this.forwards.z, this.ups.x, this.ups.y, this.ups.z);\n\n // Firefox does not support parameters as `AudioParam`\n // this.listener.positionX.value = this.positions.x;\n // this.listener.positionY.value = this.positions.y;\n // this.listener.positionZ.value = this.positions.z;\n\n // this.listener.forwardX.value = this.forwards.x;\n // this.listener.forwardY.value = this.forwards.y;\n // this.listener.forwardZ.value = this.forwards.z;\n\n // this.listener.upX.value = this.ups.x;\n // this.listener.upY.value = this.ups.y;\n // this.listener.upZ.value = this.ups.z;\n }\n\n /** @override */\n public override connect(): GainNode {\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for audio listener.\n * This method is overloaded for type interface and type check.\n * @param {keyof ListenerParams|ListenerParams} params This argument is string if getter. Otherwise, setter.\n * @return {ListenerParams[keyof ListenerParams]|Listener} Return value is parameter for audio listener if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'x'): number;\n public param(params: 'y'): number;\n public param(params: 'z'): number;\n public param(params: 'fx'): number;\n public param(params: 'fy'): number;\n public param(params: 'fz'): number;\n public param(params: 'ux'): number;\n public param(params: 'uy'): number;\n public param(params: 'uz'): number;\n public param(params: ListenerParams): Listener;\n public param(params: keyof ListenerParams | ListenerParams): ListenerParams[keyof ListenerParams] | Listener {\n if (typeof params === 'string') {\n switch (params) {\n case 'x': {\n return this.positions.x;\n }\n\n case 'y': {\n return this.positions.y;\n }\n\n case 'z': {\n return this.positions.z;\n }\n\n case 'fx': {\n return this.forwards.x;\n }\n\n case 'fy': {\n return this.forwards.y;\n }\n\n case 'fz': {\n return this.forwards.z;\n }\n\n case 'ux': {\n return this.ups.x;\n }\n\n case 'uy': {\n return this.ups.y;\n }\n\n case 'uz': {\n return this.ups.z;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'x': {\n if (typeof value === 'number') {\n this.positions.x = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'y': {\n if (typeof value === 'number') {\n this.positions.y = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'z': {\n if (typeof value === 'number') {\n this.positions.z = value;\n this.listener.setPosition(this.positions.x, this.positions.y, this.positions.z);\n }\n\n break;\n }\n\n case 'fx': {\n if (typeof value === 'number') {\n this.forwards.x = value;\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 break;\n }\n\n case 'fy': {\n if (typeof value === 'number') {\n this.forwards.y = value;\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 break;\n }\n\n case 'fz': {\n if (typeof value === 'number') {\n this.forwards.z = value;\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 break;\n }\n\n case 'ux': {\n if (typeof value === 'number') {\n this.ups.x = value;\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 break;\n }\n\n case 'uy': {\n if (typeof value === 'number') {\n this.ups.y = value;\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 break;\n }\n\n case 'uz': {\n if (typeof value === 'number') {\n this.ups.z = value;\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 break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<ListenerParams> {\n return {\n x : this.positions.x,\n y : this.positions.y,\n z : this.positions.z,\n fx: this.forwards.x,\n fy: this.forwards.y,\n fz: this.forwards.z,\n ux: this.ups.x,\n uy: this.ups.y,\n uz: this.ups.z\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { NoiseGateParams } from '../NoiseGate';\n\nimport { AudioWorkletProcessor } from '../../../worklet';\n\ninterface NoiseGateProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n noisegate: (level: number) => number;\n alloc_memory_inputs: () => number;\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Override `process` method for noise gate and Update parameters on message event.\n */\nexport class NoiseGateProcessor extends AudioWorkletProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private level = 0;\n private isActive = true;\n\n constructor() {\n super();\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | NoiseGateParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if (!this.isActive || (this.level === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as NoiseGateProcessorWebAssemblyInstance;;\n\n const linearMemory = wasm.memory.buffer;\n\n const bufferSize = input[0].length;\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs();\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, bufferSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.noisegate(this.level);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { NoiseGateProcessor } from './AudioWorkletProcessors/NoiseGateProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/noisegate.wasm';\n\nexport type NoiseGateParams = {\n state?: boolean,\n level?: number\n};\n\n/**\n * This private class is for Noise Gate.\n */\nexport class NoiseGate extends Effector {\n private processor: AudioWorkletNode;\n\n private level = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, NoiseGateProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Noise Gate) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for noise gate.\n * @param {keyof NoiseGateParams|NoiseGateParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseGateParams[keyof NoiseGateParams]|NoiseGate} Return value is parameter for noise gate if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'level'): number;\n public param(params: NoiseGateParams): NoiseGate;\n public param(params: keyof NoiseGateParams | NoiseGateParams): NoiseGateParams[keyof NoiseGateParams] | NoiseGate {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'level': {\n return this.level;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: NoiseGateParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const message: NoiseGateParams = { level: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public params(): Required<NoiseGateParams> {\n return {\n state: this.isActive,\n level: this.level\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { NoiseSuppressorParams } from '../NoiseSuppressor';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface NoiseSuppressorProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n noisesuppressor: (threshold: number, fftSize: number) => number;\n alloc_memory_inputs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for noise suppressor and Update parameters on message event.\n */\nexport class NoiseSuppressorProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private threshold = 0;\n private isActive = true;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = async (event: MessageEvent<ArrayBuffer | NoiseSuppressorParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if (!this.isActive || (this.threshold === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as NoiseSuppressorProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs(this.frameSize);\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, this.frameSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.noisesuppressor(this.threshold, this.frameSize);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, this.frameSize));\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { NoiseSuppressorProcessor } from './AudioWorkletProcessors/NoiseSuppressorProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/noisesuppressor.wasm';\n\nexport type NoiseSuppressorParams = {\n state?: boolean,\n threshold?: number\n};\n\n/**\n * This private class is for Noise Suppressor.\n */\nexport class NoiseSuppressor extends Effector {\n private processor: AudioWorkletNode;\n\n private threshold = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, NoiseSuppressorProcessor.name, {\n processorOptions: {\n frameSize: 1024\n }\n });\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Noise Suppressor) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for noise suppressor.\n * @param {keyof NoiseSuppressorParams|NoiseSuppressorParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseSuppressorParams[keyof NoiseSuppressorParams]|NoiseSuppressor} Return value is parameter for noise suppressor if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'threshold'): number;\n public param(params: NoiseSuppressorParams): NoiseSuppressor;\n public param(params: keyof NoiseSuppressorParams | NoiseSuppressorParams): NoiseSuppressorParams[keyof NoiseSuppressorParams] | NoiseSuppressor {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'threshold': {\n return this.threshold;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: NoiseSuppressorParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n if (value >= 0) {\n this.threshold = value;\n\n const message: NoiseSuppressorParams = { threshold: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<NoiseSuppressorParams> {\n return {\n state : this.isActive,\n threshold: this.threshold\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type OverDriveParams = {\n state?: boolean,\n drive?: number,\n level?: number,\n oversample?: OverSampleType\n};\n\n/**\n * Effector's subclass for OverDrive.\n */\nexport class OverDrive extends Effector {\n private shaper: WaveShaperNode;\n private inputShaper: WaveShaperNode;\n private outputShaper: WaveShaperNode;\n private inputGain: GainNode;\n private outputGain: GainNode;\n private driveInput: ConstantSourceNode;\n private level: GainNode;\n\n private drive = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = this.context.createWaveShaper();\n this.inputShaper = this.context.createWaveShaper();\n this.outputShaper = this.context.createWaveShaper();\n\n this.inputGain = this.context.createGain();\n this.outputGain = this.context.createGain();\n\n this.driveInput = this.context.createConstantSource();\n\n this.level = this.context.createGain();\n\n // Initialize parameters\n const curve = new Float32Array(1024);\n\n for (let i = 0; i < 512; i++) {\n const r = Math.tanh((4 * i) / 512) * 0.5;\n\n curve[512 + i] = r;\n curve[511 - i] = -r;\n }\n\n const inputCurve = new Float32Array(101);\n\n for (let i = 0; i < 101; i++) {\n inputCurve[i] = 0.25;\n }\n\n for (let i = 52, d1 = 0.25; i < 101; i++, d1 *= 1.1) {\n inputCurve[i] = d1;\n }\n\n const outputCurve = new Float32Array([2, 2, 2, 2, 2, 0.9, 0.5, 0.35, 0.3]);\n\n this.shaper.curve = curve;\n this.shaper.oversample = '4x';\n this.inputShaper.curve = inputCurve;\n this.outputShaper.curve = outputCurve;\n\n this.inputGain.gain.value = 0;\n this.outputGain.gain.value = 0;\n\n this.driveInput.offset.value = this.drive;\n\n this.level.gain.value = 1;\n\n // `OverDrive` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override start(_startTime?: number): void {\n if (!this.isActive || !this.paused) {\n return;\n }\n\n this.driveInput.start(this.context.currentTime);\n\n this.paused = false;\n }\n\n /** @override */\n public override stop(_stopTime?: number, _releaseTime?: number): void {\n if (!this.isActive || this.paused) {\n return;\n }\n\n this.driveInput.stop(this.context.currentTime);\n\n // Create instance of `ConstantSourceNode` again\n this.driveInput = this.context.createConstantSource();\n\n // Restore parameters\n this.driveInput.offset.value = this.drive;\n\n this.paused = true;\n\n // Connect again\n this.connect();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.shaper.disconnect(0);\n this.inputShaper.disconnect(0);\n this.outputShaper.disconnect(0);\n this.inputGain.disconnect(0);\n this.outputGain.disconnect(0);\n this.driveInput.disconnect(0);\n this.level.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) > GainNode (Input Gain) -> WaveShaperNode (OverDrive) -> GainNode (Output Gain) -> GainNode (OverDrive Level) -> GainNode (Output)\n this.input.connect(this.inputGain);\n this.inputGain.connect(this.shaper);\n this.shaper.connect(this.outputGain);\n this.outputGain.connect(this.level);\n this.level.connect(this.output);\n\n // ConstantSourceNode (Input as OverDrive) -> WaveShaperNode (Input Envelope Follower) -> AudioParam (gain as input)\n this.driveInput.connect(this.inputShaper);\n this.inputShaper.connect(this.inputGain.gain);\n\n // ConstantSourceNode (Input as OverDrive) -> WaveShaperNode (Output Envelope Follower) -> AudioParam (gain as output)\n this.driveInput.connect(this.outputShaper);\n this.outputShaper.connect(this.outputGain.gain);\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for overdrive effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof OverDriveParams|OverDriveParams} params This argument is string if getter. Otherwise, setter.\n * @return {OverDriveParams[keyof OverDriveParams]|OverDrive} Return value is parameter for overdrive effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'drive'): number;\n public param(params: 'level'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: OverDriveParams): OverDrive;\n public param(params: keyof OverDriveParams | OverDriveParams): OverDriveParams[keyof OverDriveParams] | OverDrive {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'drive': {\n return this.drive;\n }\n\n case 'level': {\n return this.level.gain.value;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'drive': {\n if (typeof value === 'number') {\n this.drive = value;\n this.driveInput.offset.value = this.drive;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level.gain.value = value;\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<OverDriveParams> {\n return {\n state : this.isActive,\n drive : this.drive,\n level : this.level.gain.value,\n oversample: this.shaper.oversample\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type Position3D = {\n x: number,\n y: number,\n z: number\n};\n\nexport type PannerParams = {\n state?: boolean,\n x?: number,\n y?: number,\n z?: number,\n ox?: number,\n oy?: number,\n oz?: number,\n refDistance?: number,\n maxDistance?: number,\n rolloffFactor?: number,\n coneInnerAngle?: number,\n coneOuterAngle?: number,\n coneOuterGain?: number,\n panningModel: PanningModelType,\n distanceModel: DistanceModelType\n};\n\n/**\n * Effector's subclass for Panner.\n */\nexport class Panner extends Effector {\n private panner: PannerNode;\n private positions: Position3D;\n private orientations: Position3D;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\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 = 'HRTF';\n this.panner.distanceModel = 'inverse';\n\n this.panner.positionX.value = this.positions.x;\n this.panner.positionY.value = this.positions.y;\n this.panner.positionZ.value = this.positions.z;\n\n this.panner.orientationX.value = this.orientations.x;\n this.panner.orientationY.value = this.orientations.y;\n this.panner.orientationZ.value = this.orientations.z;\n\n // `Panner` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Pan) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for panner.\n * This method is overloaded for type interface and type check.\n * @param {keyof PannerParams|PannerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PannerParams[keyof PannerParams]|PannerParams} Return value is parameter for panner if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'x'): number;\n public param(params: 'y'): number;\n public param(params: 'z'): number;\n public param(params: 'ox'): number;\n public param(params: 'oy'): number;\n public param(params: 'oz'): number;\n public param(params: 'refDistance'): number;\n public param(params: 'maxDistance'): number;\n public param(params: 'rolloffFactor'): number;\n public param(params: 'coneInnerAngle'): number;\n public param(params: 'coneOuterAngle'): number;\n public param(params: 'coneOuterGain'): number;\n public param(params: 'panningModel'): PanningModelType;\n public param(params: 'distanceModel'): DistanceModelType;\n public param(params: PannerParams): Panner;\n public param(params: keyof PannerParams | PannerParams): PannerParams[keyof PannerParams] | Panner {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'x': {\n return this.panner.positionX.value;\n }\n\n case 'y': {\n return this.panner.positionY.value;\n }\n\n case 'z': {\n return this.panner.positionZ.value;\n }\n\n case 'ox': {\n return this.panner.orientationX.value;\n }\n\n case 'oy': {\n return this.panner.orientationY.value;\n }\n\n case 'oz': {\n return this.panner.orientationZ.value;\n }\n\n case 'refDistance': {\n return this.panner.refDistance;\n }\n\n case 'maxDistance': {\n return this.panner.maxDistance;\n }\n\n case 'rolloffFactor': {\n return this.panner.rolloffFactor;\n }\n\n case 'coneInnerAngle': {\n return this.panner.coneInnerAngle;\n }\n\n case 'coneOuterAngle': {\n return this.panner.coneOuterAngle;\n }\n\n case 'coneOuterGain': {\n return this.panner.coneOuterGain;\n }\n\n case 'panningModel': {\n return this.panner.panningModel;\n }\n\n case 'distanceModel': {\n return this.panner.distanceModel;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'x': {\n if (typeof value === 'number') {\n this.panner.positionX.value = value;\n }\n\n break;\n }\n\n case 'y': {\n if (typeof value === 'number') {\n this.panner.positionY.value = value;\n }\n\n break;\n }\n\n case 'z': {\n if (typeof value === 'number') {\n this.panner.positionZ.value = value;\n }\n\n break;\n }\n\n case 'ox': {\n if (typeof value === 'number') {\n this.panner.orientationX.value = value;\n }\n\n break;\n }\n\n case 'oy': {\n if (typeof value === 'number') {\n this.panner.orientationY.value = value;\n }\n\n break;\n }\n\n case 'oz': {\n if (typeof value === 'number') {\n this.panner.orientationZ.value = value;\n }\n\n break;\n }\n\n case 'refDistance': {\n if (typeof value === 'number') {\n this.panner.refDistance = value;\n }\n\n break;\n }\n\n case 'maxDistance': {\n if (typeof value === 'number') {\n this.panner.maxDistance = value;\n }\n\n break;\n }\n\n case 'rolloffFactor': {\n if (typeof value === 'number') {\n this.panner.rolloffFactor = value;\n }\n\n break;\n }\n\n case 'coneInnerAngle': {\n if (typeof value === 'number') {\n this.panner.coneInnerAngle = value;\n }\n\n break;\n }\n\n case 'coneOuterAngle': {\n if (typeof value === 'number') {\n this.panner.coneOuterAngle = value;\n }\n\n break;\n }\n\n case 'coneOuterGain': {\n if (typeof value === 'number') {\n this.panner.coneOuterGain = value;\n }\n\n break;\n }\n\n case 'panningModel': {\n if ((value === 'HRTF') || (value === 'equalpower')) {\n this.panner.panningModel = value;\n }\n\n break;\n }\n\n case 'distanceModel': {\n if ((value === 'linear') || (value === 'inverse') || (value === 'exponential')) {\n this.panner.distanceModel = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PannerParams> {\n return {\n state : this.isActive,\n x : this.positions.x,\n y : this.positions.y,\n z : this.positions.z,\n ox : this.orientations.x,\n oy : this.orientations.y,\n oz : this.orientations.z,\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}\n","import { Effector } from './Effector';\n\nexport type PhaserNumberOfStages = 0 | 2 | 4 | 8 | 12 | 24;\n\nexport type PhaserParams = {\n state?: boolean,\n stage?: PhaserNumberOfStages,\n frequency?: number,\n resonance?: number,\n depth?: number,\n rate?: number,\n mix?: number,\n dry?: number,\n wet?: number\n};\n\n/**\n * Effector's subclass for Phaser.\n */\nexport class Phaser extends Effector {\n public static MAX_STAGES = 24; // The max number of All-pass Filters\n\n private numberOfStages: PhaserNumberOfStages = 12; // The default number of All-pass Filters\n private filters: BiquadFilterNode[] = [];\n private dry: GainNode;\n private wet: GainNode;\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n const filter = context.createBiquadFilter();\n\n filter.type = 'allpass';\n filter.frequency.value = 350;\n filter.Q.value = 1;\n filter.gain.value = 0; // Not used\n\n this.filters.push(filter);\n }\n\n this.dry = context.createGain();\n this.wet = context.createGain();\n\n // Initialize parameters\n this.depth.gain.value = 0;\n this.rate.value = 0;\n this.dry.gain.value = 1;\n this.wet.gain.value = 0;\n\n // `Phaser` is not connected by default\n this.deactivate();\n\n // LFO\n // GainNode (LFO) -> GainNode (Depth) -> AudioParam (frequency)\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n\n /** @override */\n public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.depth.connect(this.filters[i].frequency);\n }\n }\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n for (let i = 0; i < Phaser.MAX_STAGES; i++) {\n this.filters[i].disconnect(0);\n }\n\n this.dry.disconnect(0);\n this.wet.disconnect(0);\n\n if (this.isActive && (this.numberOfStages > 0)) {\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 (All-pass Filter x N) -> GainNode (Wet) -> 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.wet);\n this.wet.connect(this.output);\n }\n }\n\n // Phaser don't work in Firefox if there is feedback connection.\n // GainNode (Input) -> BiquadFilterNode (All-pass Filter x N) -> GainNode (Feedback) -> BiquadFilterNode (All-pass Filter x N) ...\n } else {\n // Effect OFF\n\n // GainNode (Input) -> GainNode (Output)\n this.input.connect(this.output);\n }\n\n return this.output;\n }\n\n /**\n * This method gets or sets parameters for phaser effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof PhaserParams|PhaserParams} params This argument is string if getter. Otherwise, setter.\n * @return {PhaserParams[keyof PhaserParams]|Phaser} Return value is parameter for phaser effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'stage'): PhaserNumberOfStages;\n public param(params: 'frequency'): number;\n public param(params: 'resonance'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'mix'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: PhaserParams): Phaser;\n public param(params: keyof PhaserParams | PhaserParams): PhaserParams[keyof PhaserParams] | Phaser {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'stage': {\n return this.numberOfStages;\n }\n\n case 'frequency': {\n return this.filters[0].frequency.value;\n }\n\n case 'resonance': {\n return this.filters[0].Q.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'mix': {\n return this.wet.gain.value;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'stage': {\n switch (value) {\n case 0:\n case 2:\n case 4:\n case 8:\n case 12:\n case 24: {\n this.numberOfStages = value;\n\n // Update connection\n this.connect();\n break;\n }\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n for (const filter of this.filters) {\n filter.frequency.value = value;\n }\n\n this.depth.gain.value = value * this.depthRate;\n }\n\n break;\n }\n\n case 'resonance': {\n if (typeof value === 'number') {\n for (const filter of this.filters) {\n filter.Q.value = value;\n }\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.filters[0].frequency.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'mix': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n this.dry.gain.value = 1 - this.wet.gain.value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PhaserParams> {\n return {\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.wet.gain.value,\n dry : this.dry.gain.value,\n wet : this.wet.gain.value\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { PitchShifterParams } from '../PitchShifter';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface PitchShifterProcessorebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n pitchshifter: (pitch: number, speed: number, fftSize: number, timeCursor: number) => number;\n alloc_memory_inputs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for pitch shifter and Update parameters on message event.\n */\nexport class PitchShifterProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private timeCursor = 0;\n\n private isActive = true;\n private pitch = 1;\n private speed = 1;\n\n private dry = 0;\n private wet = 1;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = async (event: MessageEvent<ArrayBuffer | PitchShifterParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'pitch': {\n if (typeof value === 'number') {\n this.pitch = value;\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n this.speed = value;\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): void {\n if (this.instance === null) {\n return;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if (!this.isActive || ((this.pitch === 1) && (this.speed === 1))) {\n for (let channelNumber = 0; channelNumber < input.length; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return;\n }\n\n // HACK:\n const wasm = this.instance.exports as PitchShifterProcessorebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0; channelNumber < input.length; channelNumber++) {\n const offsetInput = wasm.alloc_memory_inputs(this.frameSize);\n\n const inputLinearMemory = new Float32Array(linearMemory, offsetInput, this.frameSize);\n\n inputLinearMemory.set(input[channelNumber]);\n\n const offsetOutput = wasm.pitchshifter(this.pitch, this.speed, this.frameSize, this.timeCursor);\n\n const shiftedOutput = new Float32Array(linearMemory, offsetOutput, this.frameSize);\n\n if (this.dry === 0) {\n output[channelNumber].set(shiftedOutput);\n } else {\n for (let n = 0; n < this.frameSize; n++) {\n output[channelNumber][n] = (this.dry * input[channelNumber][n]) + (this.wet * shiftedOutput[n]);\n }\n }\n }\n\n this.timeCursor += this.hopSize;\n }\n}\n","import { Effector } from './Effector';\nimport { PitchShifterProcessor } from './AudioWorkletProcessors/PitchShifterProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/pitchshifter.wasm';\n\nexport type PitchShifterParams = {\n state?: boolean,\n pitch?: number,\n speed?: number,\n dry?: number,\n wet?: number\n};\n\n/**\n * Effector's subclass for Pitch Shifter.\n */\nexport class PitchShifter extends Effector {\n private processor: AudioWorkletNode;\n\n private pitch = 1;\n private speed = 1;\n\n private dry = 0;\n private wet = 1;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(this.context, PitchShifterProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Pitch Shifter) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for pitch shifter.\n * This method is overloaded for type interface and type check.\n * @param {keyof PitchShifterParams|PitchShifterParams} params This argument is string if getter. Otherwise, setter.\n * @return {PitchShifterParams[keyof PitchShifterParams]|PitchShifter} Return value is parameter for pitch shifter if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pitch'): number;\n public param(params: 'speed'): number;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: PitchShifterParams): PitchShifter;\n public param(params: keyof PitchShifterParams | PitchShifterParams): PitchShifterParams[keyof PitchShifterParams] | PitchShifter {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pitch': {\n return this.pitch;\n }\n\n case 'speed': {\n return this.speed;\n }\n\n case 'dry': {\n return this.dry;\n }\n\n case 'wet': {\n return this.wet;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: PitchShifterParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'pitch': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.pitch = value;\n\n const message: PitchShifterParams = { pitch: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.speed = value;\n\n const message: PitchShifterParams = { speed: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value <= 1)) {\n this.dry = value;\n\n const message: PitchShifterParams = { dry: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value <= 1)) {\n this.wet = value;\n\n const message: PitchShifterParams = { wet: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<PitchShifterParams> {\n return {\n state: this.isActive,\n pitch: this.pitch,\n speed: this.speed,\n dry : this.dry,\n wet : this.wet\n };\n }\n}\n","import { Effector } from '../Effector';\n\nexport type CabinetParams = {\n state?: boolean\n};\n\n/**\n * Effector's subclass for Cabinet.\n */\nexport class Cabinet extends Effector {\n private lowpass: BiquadFilterNode;\n private notch: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.lowpass = context.createBiquadFilter();\n this.notch = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 3200;\n this.lowpass.Q.value = 6;\n this.lowpass.gain.value = 0; // Not used\n\n this.notch.type = 'notch';\n this.notch.frequency.value = 8000;\n this.notch.Q.value = 1;\n this.notch.gain.value = 0; // Not used\n\n // `Cabinet` is connected by default\n this.activate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Notch) -> BiquadFilterNode (Low-pass) -> GainNode (Output)\n this.input.connect(this.notch);\n this.notch.connect(this.lowpass);\n this.lowpass.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.output;\n }\n\n /**\n * This method gets or sets parameters for cabinet.\n * This method is overloaded for type interface and type check.\n * @param {keyof CabinetParams|CabinetParams} params This argument is string if getter. Otherwise, setter.\n * @return {CabinetParams[keyof CabinetParams]} Return value is parameter for cabinet if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: CabinetParams): void;\n public param(params: keyof CabinetParams | CabinetParams): CabinetParams[keyof CabinetParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<CabinetParams> {\n return {\n state: this.isActive\n };\n }\n}\n","import type { PreampCurve } from '../Preamp';\nimport type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type PreEqualizerParams = {\n state?: boolean,\n curve?: PreampCurve,\n oversample?: OverSampleType,\n gain?: number,\n lead?: number\n};\n\nexport type PostEqualizerParams = {\n state?: boolean,\n curve?: PreampCurve,\n oversample?: OverSampleType,\n bass?: number,\n middle?: number,\n treble?: number,\n frequency?: number\n};\n\nexport type MarshallParams = {\n state?: boolean,\n level?: number,\n samples?: number,\n pre?: PreEqualizerParams,\n post?: PostEqualizerParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private shaper: WaveShaperNode;\n private preGain: GainNode;\n private leadGain: GainNode;\n private lowpass: BiquadFilterNode;\n private highpass1: BiquadFilterNode;\n private highpass2: BiquadFilterNode;\n private highpass3: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = context.createWaveShaper();\n\n this.preGain = context.createGain();\n this.leadGain = context.createGain();\n\n this.lowpass = context.createBiquadFilter();\n this.highpass1 = context.createBiquadFilter();\n this.highpass2 = context.createBiquadFilter();\n this.highpass3 = context.createBiquadFilter();\n\n // Initialize parameters\n this.shaper.oversample = '4x';\n\n this.preGain.gain.value = 0.5;\n this.leadGain.gain.value = 0.5;\n\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 3200;\n this.lowpass.Q.value = -3;\n this.lowpass.gain.value = 0; // Not used\n\n this.highpass1.type = 'highpass';\n this.highpass1.frequency.value = 80;\n this.highpass1.Q.value = -3;\n this.highpass1.gain.value = 0; // Not used\n\n this.highpass2.type = 'highpass';\n this.highpass2.frequency.value = 640;\n this.highpass2.Q.value = -3;\n this.highpass2.gain.value = 0; // Not used\n\n this.highpass3.type = 'highpass';\n this.highpass3.frequency.value = 80;\n this.highpass3.Q.value = -3;\n this.highpass3.gain.value = 0; // Not used\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Low-pass) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.highpass1);\n this.highpass1.connect(this.lowpass);\n this.lowpass.connect(this.preGain);\n this.preGain.connect(this.highpass3);\n\n // GainNode (Input) -> BiquadFilterNode (High-pass) -> GainNode (Lead-gain) -> BiquadFilterNode (High-pass)\n this.input.connect(this.highpass2);\n this.highpass2.connect(this.leadGain);\n this.leadGain.connect(this.highpass3);\n\n // BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping) -> GainNode (Output)\n this.highpass3.connect(this.shaper);\n this.shaper.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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'curve'): PreampCurve;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'gain'): number;\n public param(params: 'lead'): number;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'curve': {\n return this.shaper.curve;\n }\n\n case 'oversample': {\n return this.shaper.curve;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'lead': {\n return this.leadGain.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'curve': {\n if ((typeof value !== 'number') && (typeof value !== 'boolean')) {\n if ((value instanceof Float32Array) || (value === null)) {\n this.shaper.curve = value;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'lead': {\n if (typeof value === 'number') {\n this.leadGain.gain.value = value;\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n curve : this.shaper.curve,\n gain : this.preGain.gain.value,\n lead : this.leadGain.gain.value,\n oversample: this.shaper.oversample\n };\n }\n}\n\n/**\n * Effector's subclass for Post-Equalizer.\n */\nclass PostEqualizer extends Effector {\n private shaper: WaveShaperNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private lowpass: BiquadFilterNode;\n private highpass: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.shaper = context.createWaveShaper();\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.shaper.oversample = '4x';\n\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 240; // 240 Hz\n this.middle.frequency.value = 500; // 500 Hz\n this.treble.frequency.value = 1600; // 1.6 kHz\n\n // Set Q\n this.bass.Q.value = 0; // Not used\n this.middle.Q.value = 1.5;\n this.treble.Q.value = 0; // 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\n this.lowpass = context.createBiquadFilter();\n this.highpass = context.createBiquadFilter();\n\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = 4000;\n this.lowpass.Q.value = -3;\n this.lowpass.gain.value = 0; // Not used\n\n this.highpass.type = 'highpass';\n this.highpass.frequency.value = 40;\n this.highpass.Q.value = -3;\n this.highpass.gain.value = 0; // Not used\n\n // `PostEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> BiquadFilterNode (Low-pass) -> BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving) -> GainNode (Output)\n this.input.connect(this.lowpass);\n this.lowpass.connect(this.highpass);\n this.highpass.connect(this.shaper);\n this.shaper.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.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.output;\n }\n\n /**\n * This method gets or sets parameters for post-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostEqualizerParams|PostEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostEqualizerParams[keyof PostEqualizerParams]} Return value is parameter for post-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'curve'): PreampCurve;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'frequency'): number;\n public param(params: PostEqualizerParams): void;\n public param(params: keyof PostEqualizerParams | PostEqualizerParams): PostEqualizerParams[keyof PostEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'curve': {\n return this.shaper.curve;\n }\n\n case 'oversample': {\n return this.shaper.oversample;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'frequency': {\n return this.middle.frequency.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'curve': {\n if ((typeof value !== 'number') && (typeof value !== 'boolean')) {\n if ((value instanceof Float32Array) || (value === null)) {\n this.shaper.curve = value;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n this.shaper.oversample = value;\n }\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'frequency': {\n if (typeof value === 'number') {\n this.middle.frequency.value = value;\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PostEqualizerParams> {\n return {\n state : this.isActive,\n curve : this.shaper.curve,\n oversample: this.shaper.oversample,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n frequency : this.middle.frequency.value\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (Marshall).\n */\nexport class Marshall extends Effector {\n private preEQ: PreEqualizer;\n private postEQ: PostEqualizer;\n private cabinet: Cabinet;\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postEQ = new PostEqualizer(context);\n this.cabinet = new Cabinet(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Post-Equalizer -> Cabinet -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.postEQ.INPUT);\n this.postEQ.OUTPUT.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof MarshallParams|MarshallParams} params This argument is string if getter. Otherwise, setter.\n * @return {MarshallParams[keyof MarshallParams]|Marshall} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'pre'): MarshallParams['pre'];\n public param(params: 'post'): MarshallParams['post'];\n public param(params: 'cabinet'): CabinetParams;\n public param(params: MarshallParams): Marshall;\n public param(params: keyof MarshallParams | MarshallParams): MarshallParams[keyof MarshallParams] | Marshall {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postEQ.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postEQ.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postEQ.deactivate();\n }\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n this.preEQ.param({ curve });\n this.postEQ.param({ curve });\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n this.preEQ.param({ curve });\n this.postEQ.param({ curve });\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postEQ.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<MarshallParams> {\n return {\n state : this.isActive,\n level : this.level,\n samples: this.numberOfSamples,\n pre : this.preEQ.params(),\n post : this.postEQ.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type PreEqualizerParams = {\n state?: boolean,\n gain?: number,\n bass?: number,\n middle?: number,\n treble?: number,\n level?: number,\n samples?: number,\n oversample?: OverSampleType,\n postFilters?: boolean\n};\n\nexport type PostEqualizerParams = {\n state?: boolean,\n fc100?: number,\n fc360?: number,\n fc720?: number,\n fc1600?: number,\n fc4800?: number\n};\n\nexport type MesaBoogieParams = {\n state?: boolean,\n pre?: PreEqualizerParams,\n post?: PostEqualizerParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private preGain: GainNode;\n\n private preHighpass: BiquadFilterNode;\n private postHighpass: BiquadFilterNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private shapers: WaveShaperNode[] = [];\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n // Optional filters\n private usePostFilters = true;\n private lowpass: BiquadFilterNode;\n private highpass: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preGain = context.createGain();\n\n // Initialize parameters\n this.preGain.gain.value = 0.5;\n\n this.preHighpass = context.createBiquadFilter();\n this.postHighpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.preHighpass.type = 'highpass';\n this.postHighpass.type = 'highpass';\n\n this.preHighpass.frequency.value = 40; // 40 Hz\n this.postHighpass.frequency.value = 80; // 80 Hz\n\n this.preHighpass.Q.value = -3;\n this.postHighpass.Q.value = -3;\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 160; // 160 Hz\n this.middle.frequency.value = 284; // 284 Hz\n this.treble.frequency.value = 1200; // 1.2 kHz\n\n // Set Q\n this.middle.Q.value = 1.5;\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n // Initialize parameters\n for (let i = 0; i < 2; i++) {\n this.shapers[i] = context.createWaveShaper();\n\n this.shapers[i].curve = curve;\n this.shapers[i].oversample = '4x';\n }\n\n this.lowpass = context.createBiquadFilter();\n this.highpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.highpass.type = 'highpass';\n\n this.lowpass.frequency.value = 4000; // 4 kHz\n this.highpass.frequency.value = 40; // 40 Hz\n\n this.lowpass.Q.value = -3;\n this.highpass.Q.value = -3;\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving) -> WaveShaperNode (Clipping) -> BiquadFilterNode (Low-pass)\n this.input.connect(this.preGain);\n this.preGain.connect(this.preHighpass);\n this.preHighpass.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n this.treble.connect(this.postHighpass);\n this.postHighpass.connect(this.shapers[0]);\n\n if (this.usePostFilters) {\n // WaveShaperNode (Clipping) -> BiquadFilterNode (Low-pass) -> BiquadFilterNode (High-pass) -> WaveShaperNode (Clipping)\n this.shapers[0].connect(this.lowpass);\n this.lowpass.connect(this.highpass);\n this.highpass.connect(this.shapers[1]);\n } else {\n // WaveShaperNode (Clipping) -> WaveShaperNode (Clipping)\n this.shapers[0].connect(this.shapers[1]);\n }\n\n // WaveShaperNode (Clipping) -> GainNode (Output);\n this.shapers[1].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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'gain'): number;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: 'postFilters'): boolean;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'oversample': {\n return this.shapers[0].oversample;\n }\n\n case 'postFilters': {\n return this.usePostFilters;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 2; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 2; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n for (let i = 0; i < 2; i++) {\n this.shapers[i].oversample = value;\n }\n }\n }\n\n break;\n }\n\n case 'postFilters': {\n if (typeof value === 'boolean') {\n this.usePostFilters = value;\n this.connect();\n }\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n gain : this.preGain.gain.value,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n level : this.level,\n samples : this.numberOfSamples,\n oversample : this.shapers[0].oversample,\n postFilters: this.usePostFilters\n };\n }\n}\n\n/**\n * Effector's subclass for Post-Equalizer.\n */\nclass PostEqualizer extends Effector {\n private peakingFilters: BiquadFilterNode[] = [];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n for (let i = 0; i < 5; i++) {\n this.peakingFilters[i] = context.createBiquadFilter();\n\n // Initialize parameters\n this.peakingFilters[i].type = 'peaking';\n this.peakingFilters[i].gain.value = 0;\n }\n\n // Set cutoff frequency\n this.peakingFilters[0].frequency.value = 100; // 100 Hz\n this.peakingFilters[1].frequency.value = 360; // 360 Hz\n this.peakingFilters[2].frequency.value = 720; // 720 Hz\n this.peakingFilters[3].frequency.value = 1600; // 1.6 kHz\n this.peakingFilters[4].frequency.value = 4800; // 4.8 kHz\n\n // Set Q\n this.peakingFilters[0].Q.value = 1.5;\n this.peakingFilters[1].Q.value = 2.0;\n this.peakingFilters[2].Q.value = 2.0;\n this.peakingFilters[3].Q.value = 1.1;\n this.peakingFilters[4].Q.value = 1.2;\n\n // `PostEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n this.input.connect(this.peakingFilters[0]);\n\n for (let i = 0, len = (this.peakingFilters.length - 1); i < len; i++) {\n this.peakingFilters[i].connect(this.peakingFilters[i + 1]);\n }\n\n this.peakingFilters[4].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.output;\n }\n\n /**\n * This method gets or sets parameters for post-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostEqualizerParams|PostEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostEqualizerParams[keyof PostEqualizerParams]} Return value is parameter for post-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'fc100'): number;\n public param(params: 'fc360'): number;\n public param(params: 'fc720'): number;\n public param(params: 'fc1600'): number;\n public param(params: 'fc4800'): number;\n public param(params: PostEqualizerParams): void;\n public param(params: keyof PostEqualizerParams | PostEqualizerParams): PostEqualizerParams[keyof PostEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'fc100': {\n return this.peakingFilters[0].gain.value;\n }\n\n case 'fc360': {\n return this.peakingFilters[1].gain.value;\n }\n\n case 'fc720': {\n return this.peakingFilters[2].gain.value;\n }\n\n case 'fc1600': {\n return this.peakingFilters[3].gain.value;\n }\n\n case 'fc4800': {\n return this.peakingFilters[4].gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'fc100': {\n if (typeof value === 'number') {\n this.peakingFilters[0].gain.value = value;\n }\n\n break;\n }\n\n case 'fc360': {\n if (typeof value === 'number') {\n this.peakingFilters[1].gain.value = value;\n }\n\n break;\n }\n\n case 'fc720': {\n if (typeof value === 'number') {\n this.peakingFilters[2].gain.value = value;\n }\n\n break;\n }\n\n case 'fc1600': {\n if (typeof value === 'number') {\n this.peakingFilters[3].gain.value = value;\n }\n\n break;\n }\n\n case 'fc4800': {\n if (typeof value === 'number') {\n this.peakingFilters[4].gain.value = value;\n }\n\n break;\n }\n }\n }\n }\n /** @override */\n public override params(): Required<PostEqualizerParams> {\n return {\n state : this.isActive,\n fc100 : this.peakingFilters[0].gain.value,\n fc360 : this.peakingFilters[1].gain.value,\n fc720 : this.peakingFilters[2].gain.value,\n fc1600: this.peakingFilters[3].gain.value,\n fc4800: this.peakingFilters[4].gain.value,\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (MesaBoogie).\n */\nexport class MesaBoogie extends Effector {\n private preEQ: PreEqualizer;\n private postEQ: PostEqualizer;\n private cabinet: Cabinet;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postEQ = new PostEqualizer(context);\n this.cabinet = new Cabinet(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Cabinet -> Post-Equalizer -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.connect(this.postEQ.INPUT);\n this.postEQ.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof MesaBoogieParams|MesaBoogieParams} params This argument is string if getter. Otherwise, setter.\n * @return {MesaBoogieParams[keyof MesaBoogieParams]|MesaBoogie} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pre'): MesaBoogieParams['pre'];\n public param(params: 'post'): MesaBoogieParams['post'];\n public param(params: 'cabinet'): CabinetParams;\n public param(params: MesaBoogieParams): MesaBoogie;\n public param(params: keyof MesaBoogieParams | MesaBoogieParams): MesaBoogieParams[keyof MesaBoogieParams] | MesaBoogie {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postEQ.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postEQ.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postEQ.deactivate();\n }\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postEQ.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<MesaBoogieParams> {\n return {\n state : this.isActive,\n pre : this.preEQ.params(),\n post : this.postEQ.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { CabinetParams } from './Cabinet';\n\nimport { Effector } from '../Effector';\nimport { createCurve } from '../Preamp';\nimport { Cabinet } from './Cabinet';\n\nexport type SpeakerInches = -1 | 10 | 12 | 15;\n\nexport type PreEqualizerParams = {\n state?: boolean,\n gain?: number,\n bass?: number,\n middle?: number,\n treble?: number,\n level?: number,\n samples?: number,\n oversample?: OverSampleType\n};\n\nexport type PostFilterParams = {\n state?: boolean,\n inch?: SpeakerInches,\n tilt?: boolean\n};\n\nexport type FenderParams = {\n state?: boolean,\n pre?: PreEqualizerParams,\n post?: PostFilterParams,\n cabinet?: CabinetParams\n};\n\n/**\n * Effector's subclass for Pre-Equalizer.\n */\nclass PreEqualizer extends Effector {\n private preGain: GainNode;\n\n private highpass: BiquadFilterNode;\n\n private bass: BiquadFilterNode;\n private middle: BiquadFilterNode;\n private treble: BiquadFilterNode;\n\n private gainEdge: GainNode;\n private gainBody: GainNode;\n private gainBottom: GainNode;\n\n private shapers: WaveShaperNode[] = [];\n private iirLowpassFilters: IIRFilterNode[] = [];\n private iirHighpassFilters: IIRFilterNode[] = [];\n\n private mixer: GainNode;\n\n // for creating curve\n private level = 0;\n private numberOfSamples = 1024;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preGain = context.createGain();\n\n // Initialize parameters\n this.preGain.gain.value = 0.5;\n\n this.highpass = context.createBiquadFilter();\n\n // Initialize parameters\n this.highpass.type = 'highpass';\n this.highpass.frequency.value = 40; // 40 Hz\n this.highpass.Q.value = 1;\n\n this.bass = context.createBiquadFilter();\n this.middle = context.createBiquadFilter();\n this.treble = context.createBiquadFilter();\n\n // Initialize parameters\n this.bass.type = 'lowshelf';\n this.middle.type = 'peaking';\n this.treble.type = 'highshelf';\n\n // Set cutoff frequency\n this.bass.frequency.value = 160; // 160 Hz\n this.middle.frequency.value = 284; // 284 Hz\n this.treble.frequency.value = 1200; // 1.2 kHz\n\n // Set Q\n this.middle.Q.value = 1.5;\n\n // Set Gain\n this.bass.gain.value = 0;\n this.middle.gain.value = 0;\n this.treble.gain.value = 0;\n\n this.gainEdge = context.createGain();\n this.gainBody = context.createGain();\n this.gainBottom = context.createGain();\n\n // Initialize parameters\n this.gainEdge.gain.value = 1;\n this.gainBody.gain.value = 1;\n this.gainBottom.gain.value = 1;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n // Initialize parameters\n for (let i = 0; i < 3; i++) {\n this.shapers[i] = context.createWaveShaper();\n\n this.shapers[i].curve = curve;\n this.shapers[i].oversample = '4x';\n }\n\n const coefficient1 = (220 / context.sampleRate) * Math.PI;\n const coefficient2 = (220 / context.sampleRate) * Math.PI;\n\n const lowpassFeedforward1 = new Float32Array([coefficient1, coefficient1]);\n const lowpassFeedforward2 = new Float32Array([coefficient2, coefficient2]);\n const lowpassFeedback1 = new Float32Array([1.0 + coefficient1, -1.0 + coefficient1]);\n const lowpassFeedback2 = new Float32Array([1.0 + coefficient2, -1.0 + coefficient2]);\n\n const highpassFeedforward1 = new Float32Array([1.0, -1.0]);\n const highpassFeedforward2 = new Float32Array([1.0, -1.0]);\n const highpassFeedback1 = new Float32Array([1.0 + coefficient1, -1.0 + coefficient1]);\n const highpassFeedback2 = new Float32Array([1.0 + coefficient2, -1.0 + coefficient2]);\n\n this.iirLowpassFilters[0] = context.createIIRFilter(lowpassFeedforward1, lowpassFeedback1);\n this.iirLowpassFilters[1] = context.createIIRFilter(lowpassFeedforward2, lowpassFeedback2);\n\n this.iirHighpassFilters[0] = context.createIIRFilter(highpassFeedforward1, highpassFeedback1);\n this.iirHighpassFilters[1] = context.createIIRFilter(highpassFeedforward2, highpassFeedback2);\n\n this.mixer = context.createGain();\n\n // Initialize parameters\n this.mixer.gain.value = 1;\n\n // `PreEqualizer` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> GainNode (Pre-gain) -> BiquadFilterNode (High-pass) -> BiquadFilterNode (Bass: Low-shelving) -> BiquadFilterNode (Middle: Peaking) -> BiquadFilterNode (Treble: High-shelving)\n this.input.connect(this.preGain);\n this.preGain.connect(this.highpass);\n this.highpass.connect(this.bass);\n this.bass.connect(this.middle);\n this.middle.connect(this.treble);\n\n // Edge distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (High-pass) -> WaveShaperNode (Clipping) -> GainNode (Edge volume) -> GainNode (Mixer)\n this.treble.connect(this.iirHighpassFilters[1]);\n this.iirHighpassFilters[1].connect(this.shapers[0]);\n this.shapers[0].connect(this.gainEdge);\n this.gainEdge.connect(this.mixer);\n\n // Middle distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (High-pass) -> WaveShaperNode (Clipping) -> IIRFilterNode (Low-pass) -> GainNode (Body volume) -> GainNode (Mixer)\n this.treble.connect(this.iirHighpassFilters[0]);\n this.iirHighpassFilters[0].connect(this.shapers[1]);\n this.shapers[1].connect(this.iirLowpassFilters[1]);\n this.iirLowpassFilters[1].connect(this.gainBody);\n this.gainBody.connect(this.mixer);\n\n // Low distortion\n // BiquadFilterNode (Treble: High-shelving) -> IIRFilterNode (Low-pass) -> WaveShaperNode (Clipping) -> GainNode (Bottom volume) -> GainNode (Mixer)\n this.treble.connect(this.iirLowpassFilters[0]);\n this.iirLowpassFilters[0].connect(this.shapers[2]);\n this.shapers[2].connect(this.gainBottom);\n this.gainBottom.connect(this.mixer);\n\n\n // GainNode (Mixer) -> GainNode (Output)\n this.mixer.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.output;\n }\n\n /**\n * This method gets or sets parameters for pre-equalizer.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreEqualizerParams|PreEqualizerParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreEqualizerParams[keyof PreEqualizerParams]} Return value is parameter for pre-equalizer if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'gain'): number;\n public param(params: 'bass'): number;\n public param(params: 'middle'): number;\n public param(params: 'treble'): number;\n public param(params: 'level'): number;\n public param(params: 'samples'): number;\n public param(params: 'oversample'): OverSampleType;\n public param(params: PreEqualizerParams): void;\n public param(params: keyof PreEqualizerParams | PreEqualizerParams): PreEqualizerParams[keyof PreEqualizerParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'gain': {\n return this.preGain.gain.value;\n }\n\n case 'bass': {\n return this.bass.gain.value;\n }\n\n case 'middle': {\n return this.middle.gain.value;\n }\n\n case 'treble': {\n return this.treble.gain.value;\n }\n\n case 'level': {\n return this.level;\n }\n\n case 'samples': {\n return this.numberOfSamples;\n }\n\n case 'oversample': {\n return this.shapers[0].oversample;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'gain': {\n if (typeof value === 'number') {\n this.preGain.gain.value = value;\n }\n\n break;\n }\n\n case 'bass': {\n if (typeof value === 'number') {\n this.bass.gain.value = value;\n }\n\n break;\n }\n\n case 'middle': {\n if (typeof value === 'number') {\n this.middle.gain.value = value;\n }\n\n break;\n }\n\n case 'treble': {\n if (typeof value === 'number') {\n this.treble.gain.value = value;\n }\n\n break;\n }\n\n case 'level': {\n if (typeof value === 'number') {\n this.level = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 3; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'samples': {\n if (typeof value === 'number') {\n this.numberOfSamples = value;\n\n const curve = createCurve(this.level, this.numberOfSamples);\n\n for (let i = 0; i < 3; i++) {\n this.shapers[i].curve = curve;\n }\n }\n\n break;\n }\n\n case 'oversample': {\n if (typeof value === 'string') {\n if ((value === 'none') || (value === '2x') || (value === '4x')) {\n for (let i = 0; i < 3; i++) {\n this.shapers[i].oversample = value;\n }\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PreEqualizerParams> {\n return {\n state : this.isActive,\n gain : this.preGain.gain.value,\n bass : this.bass.gain.value,\n middle : this.middle.gain.value,\n treble : this.treble.gain.value,\n level : this.level,\n samples : this.numberOfSamples,\n oversample: this.shapers[0].oversample\n };\n }\n}\n\n/**\n * Effector's subclass for Post-filter.\n */\nclass PostFilter extends Effector {\n private cabinet: Cabinet;\n\n private inch: SpeakerInches = -1;\n private tilt = false;\n\n private speakerFilter: BiquadFilterNode;\n private tiltFilter: BiquadFilterNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n * @param {Cabinet} cabinet This argument is instance of `Cabinet`.\n */\n constructor(context: AudioContext, cabinet: Cabinet) {\n super(context);\n\n this.cabinet = cabinet;\n\n this.speakerFilter = context.createBiquadFilter();\n\n // Initialize parameters\n this.speakerFilter.type = 'peaking';\n this.speakerFilter.frequency.value = 40; // 40 Hz\n this.speakerFilter.Q.value = -3;\n this.speakerFilter.gain.value = 0;\n\n this.tiltFilter = context.createBiquadFilter();\n\n // Initialize parameters\n this.tiltFilter.type = 'highshelf';\n this.tiltFilter.frequency.value = 3200; // 3.2 kHz\n this.tiltFilter.Q.value = Math.SQRT1_2;\n this.tiltFilter.gain.value = 0;\n\n // `PostFilter` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Cabinet -> BiquadFilterNode (Speaker inch) -> BiquadFilterNode (Speaker tilt) -> GainNode (Output)\n this.input.connect(this.cabinet.INPUT);\n this.cabinet.OUTPUT.connect(this.speakerFilter);\n this.speakerFilter.connect(this.tiltFilter);\n this.tiltFilter.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.output;\n }\n\n /**\n * This method gets or sets parameters for post-filter.\n * This method is overloaded for type interface and type check.\n * @param {keyof PostFilterParams|PostFilterParams} params This argument is string if getter. Otherwise, setter.\n * @return {PostFilterParams[keyof PostFilterParams]} Return value is parameter for post-filter if getter.\n */\n public param(params: 'state'): boolean;\n public param(params: 'inch'): SpeakerInches;\n public param(params: 'tilt'): boolean;\n public param(params: PostFilterParams): void;\n public param(params: keyof PostFilterParams | PostFilterParams): PostFilterParams[keyof PostFilterParams] | void {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'inch': {\n return this.inch;\n }\n\n case 'tilt': {\n return this.tilt;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n } else {\n this.deactivate();\n }\n }\n\n break;\n }\n\n case 'inch': {\n if (typeof value === 'number') {\n switch (value) {\n case -1: {\n this.inch = -1;\n\n this.speakerFilter.frequency.value = 40;\n this.speakerFilter.Q.value = Math.SQRT1_2;\n this.speakerFilter.gain.value = 0;\n\n break;\n }\n\n case 10: {\n this.inch = 10;\n\n this.speakerFilter.frequency.value = 120;\n this.speakerFilter.Q.value = 3;\n this.speakerFilter.gain.value = 9;\n\n break;\n }\n\n case 12: {\n this.inch = 12;\n\n this.speakerFilter.frequency.value = 80;\n this.speakerFilter.Q.value = 6;\n this.speakerFilter.gain.value = 10;\n\n break;\n }\n\n case 15: {\n this.inch = 15;\n\n this.speakerFilter.frequency.value = 60;\n this.speakerFilter.Q.value = 9;\n this.speakerFilter.gain.value = 12;\n\n break;\n }\n }\n }\n\n break;\n }\n\n case 'tilt': {\n if (typeof value === 'boolean') {\n this.tilt = value;\n\n if (this.tilt) {\n this.tiltFilter.gain.value = 6;\n } else {\n this.tiltFilter.gain.value = 0;\n }\n }\n\n break;\n }\n }\n }\n }\n\n /** @override */\n public override params(): Required<PostFilterParams> {\n return {\n state: this.isActive,\n inch : this.inch,\n tilt : this.tilt\n };\n }\n}\n\n/**\n * Effector's subclass for Preamplifier (Fender).\n */\nexport class Fender extends Effector {\n private preEQ: PreEqualizer;\n private postFilter: PostFilter;\n private cabinet: Cabinet;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.cabinet = new Cabinet(context);\n\n this.preEQ = new PreEqualizer(context);\n this.postFilter = new PostFilter(context, this.cabinet);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> Pre-Equalizer -> Post-Filter (-> Cabinet) -> GainNode (Output)\n this.input.connect(this.preEQ.INPUT);\n this.preEQ.OUTPUT.connect(this.postFilter.INPUT);\n this.postFilter.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof FenderParams|FenderParams} params This argument is string if getter. Otherwise, setter.\n * @return {FenderParams[keyof FenderParams]|Fender} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'pre'): FenderParams['pre']\n public param(params: 'post'): FenderParams['post']\n public param(params: 'cabinet'): CabinetParams;\n public param(params: FenderParams): Fender;\n public param(params: keyof FenderParams | FenderParams): FenderParams[keyof FenderParams] | Fender {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'pre': {\n return this.preEQ.params();\n }\n\n case 'post': {\n return this.postFilter.params();\n }\n\n case 'cabinet': {\n return this.cabinet.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preEQ.activate();\n this.postFilter.activate();\n } else {\n this.deactivate();\n this.preEQ.deactivate();\n this.postFilter.deactivate();\n }\n }\n\n break;\n }\n\n case 'pre': {\n if (typeof value === 'object') {\n this.preEQ.param(value);\n }\n\n break;\n }\n\n case 'post': {\n if (typeof value === 'object') {\n this.postFilter.param(value);\n }\n\n break;\n }\n\n case 'cabinet': {\n if (typeof value === 'object') {\n this.cabinet.param(value);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<FenderParams> {\n return {\n state : this.isActive,\n pre : this.preEQ.params(),\n post : this.postFilter.params(),\n cabinet: this.cabinet.params()\n };\n }\n}\n","import type { MarshallParams } from './Preamps/Marshall';\nimport type { MesaBoogieParams } from './Preamps/MesaBoogie';\nimport type { FenderParams } from './Preamps/Fender';\n\nimport { Effector } from './Effector';\nimport { Marshall } from './Preamps/Marshall';\nimport { MesaBoogie } from './Preamps/MesaBoogie';\nimport { Fender } from './Preamps/Fender';\n\nexport type PreampType = 'marshall' | 'mesa/boogie' | 'fender';\n\nexport type PreampCurve = Float32Array<ArrayBuffer> | null;\n\nexport type PreampParams = {\n state?: boolean,\n type?: PreampType,\n preamp?: MarshallParams | MesaBoogieParams | FenderParams\n};\n\n/**\n * This function creates instance of `Float32Array` for `WaveShaperNode`.\n * @param {number} level This argument is preamp effect level.\n * @param {number} numberOfSamples This argument is curve size.\n * @return {Float32Array|null} Return value is `WaveShaperNode`'s 'curve'.\n */\nexport function createCurve(level: number, numberOfSamples: number): PreampCurve {\n const index = Math.trunc((numberOfSamples - 1) / 2);\n\n const curves = new Float32Array(numberOfSamples);\n\n const d = (10 ** ((level / 5.0) - 1.0)) - 0.1;\n const c = (d / 5.0) + 1.0;\n\n let peak = 0.4;\n\n if (c === 1) {\n peak = 1.0;\n } else if ((c > 1) && (c < 1.04)) {\n peak = (-15.5 * c) + 16.52;\n }\n\n for (let i = 0; i < index; i++) {\n curves[index + i] = peak * (+1 - (c ** -i) + (i * (c ** -index)) / index);\n curves[index - i] = peak * (-1 + (c ** -i) - (i * (c ** -index)) / index);\n }\n\n curves[index] = 0;\n\n return curves;\n}\n\n/**\n * Effector's subclass for Preamplifier.\n */\nexport class Preamp extends Effector {\n private type: PreampType = 'marshall';\n private preamp: Marshall | MesaBoogie | Fender;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.preamp = new Marshall(context);\n\n // `Preamp` is not connected by default\n this.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\n this.input.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // Create preamp connections\n this.preamp.connect();\n\n // GainNode (INPUT) -> Preamplifier -> GainNode (Output)\n this.input.connect(this.preamp.INPUT);\n this.preamp.OUTPUT.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.output;\n }\n\n /**\n * This method gets or sets parameters for preamp effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof PreampParams|PreampParams} params This argument is string if getter. Otherwise, setter.\n * @return {PreampParams[keyof PreampParams]|Marshall|MesaBoogie|Fender} Return value is parameter for preamp effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): PreampType;\n public param(params: 'preamp'): PreampParams['preamp'];\n public param(params: PreampParams): Marshall | MesaBoogie | Fender;\n public param(params: keyof PreampParams | PreampParams): PreampParams[keyof PreampParams] | Marshall | MesaBoogie | Fender {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.type;\n }\n\n case 'preamp': {\n return this.preamp.params();\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n if (value) {\n this.activate();\n this.preamp.activate();\n } else {\n this.deactivate();\n this.preamp.deactivate();\n }\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n switch (value) {\n case 'marshall': {\n this.type = 'marshall';\n this.preamp = new Marshall(this.context);\n break;\n }\n\n case 'mesa/boogie': {\n this.type = 'mesa/boogie';\n this.preamp = new MesaBoogie(this.context);\n break;\n }\n\n case 'fender': {\n this.type = 'fender';\n this.preamp = new Fender(this.context);\n break;\n }\n }\n\n this.connect();\n }\n\n break;\n }\n\n case 'preamp': {\n if (typeof value === 'object') {\n if (this.preamp instanceof Marshall) {\n const v: MarshallParams = value;\n\n this.preamp.param(v);\n }\n\n if (this.preamp instanceof MesaBoogie) {\n const v: MesaBoogieParams = value;\n\n this.preamp.param(v);\n }\n\n if (this.preamp instanceof Fender) {\n const v: FenderParams = value;\n\n this.preamp.param(v);\n }\n }\n\n break;\n }\n }\n }\n\n return this.preamp;\n }\n\n /** @override */\n public override params(): Required<PreampParams> {\n return {\n state : this.isActive,\n type : this.type,\n preamp: this.preamp.params()\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type ReverbErrorText = 'error' | 'timeout' | 'decode';\n\nexport type ReverbParams = {\n state?: boolean,\n buffer?: number | AudioBuffer | null,\n dry?: number,\n wet?: number,\n tone?: number\n};\n\n/**\n * Effector's subclass for Reverb.\n */\nexport class Reverb extends Effector {\n private convolver: ConvolverNode;\n private dry: GainNode;\n private wet: GainNode;\n private tone: BiquadFilterNode;\n\n private rirs: AudioBuffer[] = [];\n\n // If error occurs at least one, this method aborts the all of connections.\n // Therefore, this flag are shared with the all of `XMLHttpRequest` instances.\n private loadError = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\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 = 'lowpass';\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.deactivate();\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Reverb) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for reverb effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof ReverbParams|ReverbParams} params This argument is string if getter. Otherwise, setter.\n * @return {ReverbParams[keyof ReverbParams]|Reverb} Return value is parameter for reverb effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'buffer'): AudioBuffer | null;\n public param(params: 'dry'): number;\n public param(params: 'wet'): number;\n public param(params: 'tone'): number;\n public param(params: ReverbParams): Reverb;\n public param(params: keyof ReverbParams | ReverbParams): ReverbParams[keyof ReverbParams] | Reverb {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'buffer': {\n return this.convolver.buffer;\n }\n\n case 'dry': {\n return this.dry.gain.value;\n }\n\n case 'wet': {\n return this.wet.gain.value;\n }\n\n case 'tone': {\n return this.tone.frequency.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'buffer': {\n if (typeof value === 'number') {\n if ((value >= 0) && (value < this.rirs.length)) {\n this.convolver.buffer = this.rirs[value];\n this.connect();\n }\n } else if (value instanceof AudioBuffer) {\n this.convolver.buffer = value;\n this.connect();\n } else if (value === null) {\n this.convolver.buffer = null;\n\n // If `buffer` in `ConvolverNode` is `null` after setting instance of `AudioBuffer`, `Reverb` is not OFF (Maybe, it is bug ?)\n // Therefore, `Reverb` is OFF by disconnecting `AudioNode`s.\n this.input.disconnect(0);\n this.input.connect(this.output);\n }\n\n break;\n }\n\n case 'dry': {\n if (typeof value === 'number') {\n this.dry.gain.value = value;\n }\n\n break;\n }\n\n case 'wet': {\n if (typeof value === 'number') {\n this.wet.gain.value = value;\n }\n\n break;\n }\n\n case 'tone': {\n if (typeof value === 'number') {\n this.tone.frequency.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method sets instance of `AudioBuffer` to `ConvolverNode`.\n * @param {ArrayBuffer|AudioBuffer} impulse This argument is in order to convolve impulse response.\n * This argument is instance of `AudioBuffer` or `ArrayBuffer` for impulse response.\n * @param {function} errorCallback This argument is invoked on decode failure.\n * @return {Reverb} Return value is for method chain.\n */\n public add(impulse: ArrayBuffer | AudioBuffer, errorCallback?: (error: Error) => void): Reverb {\n if (impulse instanceof AudioBuffer) {\n this.convolver.buffer = impulse;\n this.rirs.push(impulse); // Add to preset\n } else if (impulse instanceof ArrayBuffer) {\n const successCallback = (buffer: AudioBuffer) => {\n this.convolver.buffer = buffer;\n this.rirs.push(buffer); // Add to preset\n };\n\n this.context.decodeAudioData(impulse, successCallback, (errorCallback ?? (() => {})));\n }\n\n return this;\n }\n\n /**\n * This method creates and appends to Reverb presets instance of `AudioBuffer` by Ajax.\n * @property {Array<string>|Array<AudioBuffer>} rirs This argument is array that contains URL or instance of `AudioBuffer` for impulse response.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n public preset(params: {\n rirs: string[] | AudioBuffer[];\n timeout?: number;\n successCallback?(event: ProgressEvent): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: ReverbErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { rirs, timeout, successCallback, errorCallback, progressCallback } = params;\n\n for (let index = 0, len = rirs.length; index < len; index++) {\n const rir = rirs[index];\n\n if (typeof rir === 'string') {\n // Get instance of `AudioBuffer` from designated URLs.\n this.load({ rir, index, timeout, successCallback, errorCallback, progressCallback });\n } else {\n // Get instance of `AudioBuffer` directly\n this.rirs[index] = rir;\n }\n }\n }\n\n /** @override */\n public override params(): Required<Omit<ReverbParams, 'buffer'>> {\n return {\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\n /** @override */\n public override activate() {\n this.isActive = true;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /** @override */\n public override deactivate() {\n this.isActive = false;\n\n // Update connection\n this.connect();\n\n // Type inference\n return this;\n }\n\n /**\n * This method retrives `ArrayBuffer` and creates instance of `AudioBuffer`.\n * @property {string} url This argument is resource URL for one-shot audio.\n * @property {number} index This argument is in order to assign instance of `AudioBuffer`.\n * @property {number} timeout This argument is Ajax timeout.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n private load(params: {\n rir: string;\n index: number;\n timeout?: number;\n successCallback?(event: ProgressEvent): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: ReverbErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { rir, index, timeout, successCallback, errorCallback, progressCallback } = params;\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'timeout');\n }\n\n this.loadError = true;\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (this.loadError) {\n xhr.abort();\n } else if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'error');\n }\n\n this.loadError = true;\n };\n\n // Success\n xhr.onload = (event: ProgressEvent) => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n const decodeSuccessCallback = (buffer: AudioBuffer) => {\n this.rirs[index] = buffer;\n\n // Creating instance of `AudioBuffer` has completed ?\n for (const rir of this.rirs) {\n if (rir === undefined) {\n return;\n }\n }\n\n if (successCallback) {\n successCallback(event);\n }\n };\n\n const decodeErrorCallback = (error: Error) => {\n if (errorCallback) {\n errorCallback(error, 'decode');\n }\n };\n\n this.context.decodeAudioData(arrayBuffer, decodeSuccessCallback, decodeErrorCallback);\n }\n };\n\n xhr.open('GET', rir, true);\n xhr.responseType = 'arraybuffer'; // XMLHttpRequest Level 2\n xhr.send(null);\n }\n}\n","import { Effector } from './Effector';\n\nexport type RingmodulatorParams = {\n state?: boolean,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Ring Modulator.\n */\nexport class Ringmodulator extends Effector {\n private amplitude: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.amplitude = context.createGain();\n\n // Initialize parameter\n this.amplitude.gain.value = 0; // 0 +- depth\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Ringmodulator` is not connected by default\n this.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Ring Modulator) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for ring modulator effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof RingmodulatorParams|RingmodulatorParams} params This argument is string if getter. Otherwise, setter.\n * @return {RingmodulatorParams[keyof RingmodulatorParams]|Autopanner} Return value is parameter for ring modulator effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: RingmodulatorParams): Ringmodulator;\n public param(params: keyof RingmodulatorParams | RingmodulatorParams): RingmodulatorParams[keyof RingmodulatorParams] | Ringmodulator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<RingmodulatorParams> {\n return {\n state: this.isActive,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type StereoParams = {\n state?: boolean,\n time?: number\n};\n\n/**\n * Effector's subclass for Stereo.\n */\nexport class Stereo extends Effector {\n public static MAX_DELAY_TIME = 1; // Max delay time is 1000 [ms]\n\n private splitter: ChannelSplitterNode;\n private merger: ChannelMergerNode;\n private delay: DelayNode;\n private gainL: GainNode;\n private gainR: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.splitter = context.createChannelSplitter(2);\n this.merger = context.createChannelMerger(2);\n this.delay = context.createDelay(Stereo.MAX_DELAY_TIME);\n this.gainL = context.createGain();\n this.gainR = context.createGain();\n\n // Initialize parameters\n this.delay.delayTime.value = 0;\n\n this.gainL.gain.value = +1;\n this.gainR.gain.value = -1;\n\n this.deactivate();\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.delay.disconnect(0);\n this.splitter.disconnect(0);\n this.splitter.disconnect(1);\n this.gainL.disconnect(0);\n this.gainR.disconnect(0);\n this.merger.disconnect(0);\n\n if (this.isActive) {\n // Effect ON\n\n // GainNode (Input) -> ChannelMergerNode\n this.input.connect(this.merger, 0, 0);\n this.input.connect(this.merger, 0, 1);\n\n // GainNode (Input) -> DelayNode -> ChannelSplitterNode -> GainNode (L) / (R) -> ChannelMergerNode -> GainNode (Output)\n this.input.connect(this.delay);\n this.delay.connect(this.splitter);\n this.splitter.connect(this.gainL, 0, 0);\n this.splitter.connect(this.gainR, 1, 0);\n this.gainL.connect(this.merger, 0, 0);\n this.gainR.connect(this.merger, 0, 1);\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.output;\n }\n\n /**\n * This method gets or sets parameters for stereo effector\n * This method is overloaded for type interface and type check.\n * @param {keyof StereoParams|StereoParams} params This argument is string if getter. Otherwise, setter.\n * @return {StereoParams[keyof StereoParams]|Stereo} Return value is parameter for stereo effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'time'): number;\n public param(params: StereoParams): Stereo;\n public param(params: keyof StereoParams | StereoParams): StereoParams[keyof StereoParams] | Stereo {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'time': {\n return this.delay.delayTime.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.delay.delayTime.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<StereoParams> {\n return {\n state: this.isActive,\n time : this.delay.delayTime.value\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type TremoloParams = {\n state?: boolean,\n type?: OscillatorType,\n depth?: number,\n rate?: number\n};\n\n/**\n * Effector's subclass for Tremolo.\n */\nexport class Tremolo extends Effector {\n private amplitude: GainNode;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.amplitude = context.createGain();\n\n // Initialize parameter\n this.amplitude.gain.value = 1; // 1 +- depth\n this.lfo.type = 'sine';\n this.depth.gain.value = 0;\n this.rate.value = 0;\n\n // `Tremolo` is not connected by default\n this.deactivate();\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 public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.amplitude.gain);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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 (Tremolo) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for tremolo effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof TremoloParams|TremoloParams} params This argument is string if getter. Otherwise, setter.\n * @return {TremoloParams[keyof TremoloParams]|Tremolo} Return value is parameter for tremolo effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'type'): OscillatorType;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: TremoloParams): Tremolo;\n public param(params: keyof TremoloParams | TremoloParams): TremoloParams[keyof TremoloParams] | Tremolo {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.lfo.type;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.lfo.type = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<TremoloParams> {\n return {\n state: this.isActive,\n type : this.lfo.type,\n depth: this.depth.gain.value,\n rate : this.rate.value\n };\n }\n}\n","import type { Inputs, Outputs } from '../../../worklet';\nimport type { VocalCancelerParams, VocalCancelerAlgorithm } from '../VocalCanceler';\n\nimport { OverlapAddProcessor } from '../../../worklet';\n\ninterface VocalCancelerProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n vocalcancelerL: (depth: number, bufferSize: number) => number;\n vocalcancelerR: (depth: number, bufferSize: number) => number;\n vocalcanceler_on_spectrum: (sampleRate: number, minFrequency: number, maxFrequency: number, threshold: number, fftSize: number) => number;\n alloc_memory_inputLs: (bufferSize: number) => number;\n alloc_memory_inputRs: (bufferSize: number) => number;\n};\n\n/**\n * This class extends `OverlapAddProcessor`.\n * Override `processOverlapAdd` method for vocal canceler and Update parameters on message event.\n */\nexport class VocalCancelerProcessor extends OverlapAddProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private algorithm: VocalCancelerAlgorithm = 'time';\n private depth = 0;\n private minFrequency = 200;\n private maxFrequency = 8000;\n private threshold = 0.05;\n\n private isActive = true;\n\n constructor(options: AudioWorkletNodeOptions) {\n super(options);\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | VocalCancelerParams>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n for (const [key, value] of Object.entries(event.data)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'algorithm': {\n if (typeof value === 'string') {\n this.algorithm = value;\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth = value;\n }\n\n break;\n }\n\n case 'minFrequency': {\n if (typeof value === 'number') {\n this.minFrequency = value;\n }\n\n break;\n }\n\n case 'maxFrequency': {\n if (typeof value === 'number') {\n this.maxFrequency = value;\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n }\n\n break;\n }\n }\n }\n }\n };\n }\n\n /** @override */\n protected override processOverlapAdd(inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length === 0) || (output.length === 0)) {\n return true;\n }\n\n if ((input.length !== 2) || (output.length !== 2)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n if (!this.isActive || (this.depth === 0)) {\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n\n // HACK:\n const wasm = this.instance.exports as VocalCancelerProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetInputL = wasm.alloc_memory_inputLs(this.frameSize);\n const offsetInputR = wasm.alloc_memory_inputRs(this.frameSize);\n\n const inputLinearMemoryL = new Float32Array(linearMemory, offsetInputL, this.frameSize);\n const inputLinearMemoryR = new Float32Array(linearMemory, offsetInputR, this.frameSize);\n\n inputLinearMemoryL.set(input[0]);\n inputLinearMemoryR.set(input[1]);\n\n switch (this.algorithm) {\n case 'time': {\n const offsetOutputL = wasm.vocalcancelerL(this.depth, this.frameSize);\n const offsetOutputR = wasm.vocalcancelerR(this.depth, this.frameSize);\n\n output[0].set(new Float32Array(linearMemory, offsetOutputL, this.frameSize));\n output[1].set(new Float32Array(linearMemory, offsetOutputR, this.frameSize));\n\n break;\n }\n\n case 'spectrum': {\n const offsetOutputL = wasm.vocalcanceler_on_spectrum(sampleRate, this.minFrequency, this.maxFrequency, this.threshold, this.frameSize);\n const offsetOutputR = offsetOutputL + (this.frameSize * Float32Array.BYTES_PER_ELEMENT);\n\n const canceledInputLs = new Float32Array(linearMemory, offsetOutputL, this.frameSize);\n const canceledInputRs = new Float32Array(linearMemory, offsetOutputR, this.frameSize);\n\n for (let n = 0; n < this.frameSize; n++) {\n output[0][n] = ((1 - this.depth) * input[0][n]) + (this.depth * canceledInputLs[n]);\n output[1][n] = ((1 - this.depth) * input[1][n]) + (this.depth * canceledInputRs[n]);\n }\n\n break;\n }\n }\n\n return true;\n }\n}\n","import { Effector } from './Effector';\nimport { VocalCancelerProcessor } from './AudioWorkletProcessors/VocalCancelerProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './AudioWorkletProcessors/WebAssemblyModules/vocalcanceler.wasm';\n\nexport type VocalCancelerAlgorithm = 'time' | 'spectrum';\n\nexport type VocalCancelerParams = {\n state?: boolean,\n algorithm?: VocalCancelerAlgorithm,\n depth?: number,\n minFrequency?: number,\n maxFrequency?: number,\n threshold?: number\n};\n\n/**\n * This private class is for Vocal Canceler.\n */\nexport class VocalCanceler extends Effector {\n private processor: AudioWorkletNode;\n\n private algorithm: VocalCancelerAlgorithm = 'time';\n private minFrequency = 200;\n private maxFrequency = 8000;\n private threshold = 0.05;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.depth.gain.value = 0;\n\n this.processor = new AudioWorkletNode(this.context, VocalCancelerProcessor.name);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n this.activate();\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /** @override */\n public override start(): void {\n }\n\n /** @override */\n public override stop(): void {\n }\n\n /** @override */\n public override connect(): GainNode {\n // Clear connection\n this.input.disconnect(0);\n this.processor.disconnect(0);\n\n if (this.isActive) {\n // GainNode (Input) -> AudioWorkletNode (Vocal Canceler) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for vocal canceler.\n * @param {keyof VocalCancelerParams|VocalCancelerParams} params This argument is string if getter. Otherwise, setter.\n * @return {VocalCancelerParams[keyof VocalCancelerParams]|VocalCanceler} Return value is parameter for vocal canceler if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'algorithm'): VocalCancelerAlgorithm;\n public param(params: 'depth'): number;\n public param(params: 'minFrequency'): number;\n public param(params: 'maxFrequency'): number;\n public param(params: 'threshold'): number;\n public param(params: VocalCancelerParams): VocalCanceler;\n public param(params: keyof VocalCancelerParams | VocalCancelerParams): VocalCancelerParams[keyof VocalCancelerParams] | VocalCanceler {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'algorithm': {\n return this.algorithm;\n }\n\n case 'depth': {\n return this.depth.gain.value;\n }\n\n case 'minFrequency': {\n return this.minFrequency;\n }\n\n case 'maxFrequency': {\n return this.maxFrequency;\n }\n\n case 'threshold': {\n return this.threshold;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n\n const message: VocalCancelerParams = { state: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'algorithm': {\n if (typeof value === 'string') {\n this.algorithm = value;\n\n const message: VocalCancelerParams = { algorithm: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depth.gain.value = value;\n\n const message: VocalCancelerParams = { depth: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'minFrequency': {\n if (typeof value === 'number') {\n this.minFrequency = value;\n\n const message: VocalCancelerParams = { minFrequency: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'maxFrequency': {\n if (typeof value === 'number') {\n this.maxFrequency = value;\n\n const message: VocalCancelerParams = { maxFrequency: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n\n case 'threshold': {\n if (typeof value === 'number') {\n this.threshold = value;\n\n const message: VocalCancelerParams = { threshold: value };\n\n this.processor.port.postMessage(message);\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets vocal canceler parameters as associative array.\n * @return {VocalCancelerParams}\n */\n public params(): Required<VocalCancelerParams> {\n return {\n state : this.isActive,\n algorithm : this.algorithm,\n depth : this.depth.gain.value,\n minFrequency: this.minFrequency,\n maxFrequency: this.maxFrequency,\n threshold : this.threshold\n };\n }\n}\n","import { Effector } from './Effector';\n\nexport type WahParams = {\n state?: boolean,\n auto?: boolean,\n cutoff?: number,\n depth?: number,\n rate?: number,\n resonance?: number\n};\n\n/**\n * Effector's subclass for Wah.\n */\nexport class Wah extends Effector {\n private auto = false;\n\n private lowpass: BiquadFilterNode;\n private envelopeFollower: WaveShaperNode;\n private sensitivity: BiquadFilterNode;\n\n private depthRate = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.lowpass = context.createBiquadFilter();\n this.envelopeFollower = context.createWaveShaper();\n this.sensitivity = context.createBiquadFilter();\n\n // Initialize parameters\n this.lowpass.type = 'lowpass';\n this.lowpass.frequency.value = this.auto ? 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 = 'lowpass';\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\n // `Wah` is not connected by default\n this.deactivate();\n\n this.connect();\n }\n\n /** @override */\n public override stop(stopTime?: number, releaseTime?: number): void {\n super.stop(stopTime, releaseTime);\n\n if (!this.auto && this.isActive) {\n // Connect `AudioNode`s again\n this.lfo.connect(this.depth);\n this.depth.connect(this.lowpass.frequency);\n }\n }\n\n /** @override */\n public override connect(): GainNode {\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.auto) {\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) -> 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.output;\n }\n\n /**\n * This method gets or sets parameters for wah effector.\n * This method is overloaded for type interface and type check.\n * @param {keyof WahParams|WahParams} params This argument is string if getter. Otherwise, setter.\n * @return {WahParams[keyof WahParams]|Wah} Return value is parameter for wah effector if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'auto'): boolean;\n public param(params: 'cutoff'): number;\n public param(params: 'depth'): number;\n public param(params: 'rate'): number;\n public param(params: 'resonance'): number;\n public param(params: WahParams): Wah;\n public param(params: keyof WahParams | WahParams): WahParams[keyof WahParams] | Wah {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'auto': {\n return this.auto;\n }\n\n case 'cutoff': {\n return this.auto ? this.sensitivity.frequency.value : this.lowpass.frequency.value;\n }\n\n case 'depth': {\n return this.depthRate;\n }\n\n case 'rate': {\n return this.rate.value;\n }\n\n case 'resonance': {\n return this.auto ? this.sensitivity.Q.value : this.lowpass.Q.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'auto': {\n if (typeof value === 'boolean') {\n this.auto = value;\n this.connect();\n }\n\n break;\n }\n\n case 'cutoff': {\n if (typeof value === 'number') {\n if (this.auto) {\n this.sensitivity.frequency.value = value;\n this.lowpass.frequency.value = 20;\n } else {\n this.lowpass.frequency.value = value;\n }\n }\n\n break;\n }\n\n case 'depth': {\n if (typeof value === 'number') {\n this.depthRate = value;\n this.depth.gain.value = this.auto ? 10000 * value : this.lowpass.frequency.value * value;\n }\n\n break;\n }\n\n case 'rate': {\n if (typeof value === 'number') {\n this.rate.value = value;\n }\n\n break;\n }\n\n case 'resonance': {\n if (typeof value === 'number') {\n if (this.auto) {\n this.sensitivity.Q.value = value;\n this.lowpass.Q.value = 1;\n } else {\n this.lowpass.Q.value = value;\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /** @override */\n public override params(): Required<WahParams> {\n return {\n state : this.isActive,\n auto : this.auto,\n cutoff : this.auto ? this.sensitivity.frequency.value : this.lowpass.frequency.value,\n depth : this.auto ? this.depth.gain.value : this.depthRate,\n rate : this.rate.value,\n resonance: this.auto ? this.sensitivity.Q.value : this.lowpass.Q.value\n };\n }\n}\n","import type { Connectable } from '../interfaces';\nimport type { Effector } from './Effectors/Effector';\nimport type { AutopannerParams } from './Effectors/Autopanner';\nimport type { BitCrusherParams } from './Effectors/BitCrusher';\nimport type { ChorusParams } from './Effectors/Chorus';\nimport type { CompressorParams } from './Effectors/Compressor';\nimport type { DelayParams } from './Effectors/Delay';\nimport type { EnvelopeGeneratorParams } from './Effectors/EnvelopeGenerator';\nimport type { EqualizerParams } from './Effectors/Equalizer';\nimport type { FilterParams } from './Effectors/Filter';\nimport type { FlangerParams } from './Effectors/Flanger';\nimport type { FuzzParams } from './Effectors/Fuzz';\nimport type { ListenerParams } from './Effectors/Listener';\nimport type { NoiseGateParams } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressorParams } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDriveParams } from '../SoundModule/Effectors/OverDrive';\nimport type { PannerParams } from './Effectors/Panner';\nimport type { PhaserParams } from './Effectors/Phaser';\nimport type { PitchShifterParams } from './Effectors/PitchShifter';\nimport type { PreampParams } from './Effectors/Preamp';\nimport type { ReverbParams } from './Effectors/Reverb';\nimport type { RingmodulatorParams } from './Effectors/Ringmodulator';\nimport type { StereoParams } from './Effectors/Stereo';\nimport type { TremoloParams } from './Effectors/Tremolo';\nimport type { VocalCancelerParams } from './Effectors/VocalCanceler';\nimport type { WahParams } from './Effectors/Wah';\n\nimport { SoundModuleProcessor } from './SoundModuleProcessor';\nimport { Analyser } from './Analyser';\nimport { Recorder } from './Recorder';\nimport { Autopanner } from './Effectors/Autopanner';\nimport { BitCrusher } from './Effectors/BitCrusher';\nimport { Chorus } from './Effectors/Chorus';\nimport { Compressor } from './Effectors/Compressor';\nimport { Delay } from './Effectors/Delay';\nimport { EnvelopeGenerator } from './Effectors/EnvelopeGenerator';\nimport { Equalizer } from './Effectors/Equalizer';\nimport { Filter } from './Effectors/Filter';\nimport { Flanger } from './Effectors/Flanger';\nimport { Fuzz } from './Effectors/Fuzz';\nimport { Listener } from './Effectors/Listener';\nimport { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport { Panner } from './Effectors/Panner';\nimport { Phaser } from './Effectors/Phaser';\nimport { PitchShifter } from './Effectors/PitchShifter';\nimport { Preamp } from './Effectors/Preamp';\nimport { Reverb } from './Effectors/Reverb';\nimport { Ringmodulator } from './Effectors/Ringmodulator';\nimport { Stereo } from './Effectors/Stereo';\nimport { Tremolo } from './Effectors/Tremolo';\nimport { VocalCanceler } from './Effectors/VocalCanceler';\nimport { Wah } from './Effectors/Wah';\n\nexport type Module =\n Analyser |\n Recorder |\n Autopanner |\n BitCrusher |\n Chorus |\n Compressor |\n Delay |\n EnvelopeGenerator |\n Equalizer |\n Filter |\n Flanger |\n Fuzz |\n Listener |\n NoiseGate |\n NoiseSuppressor |\n OverDrive |\n Panner |\n Phaser |\n PitchShifter |\n Preamp |\n Reverb |\n Ringmodulator |\n Stereo |\n Tremolo |\n VocalCanceler |\n Wah;\n\nexport type ModuleName =\n 'analyser' |\n 'recorder' |\n 'autopanner' |\n 'bitcrusher' |\n 'chorus' |\n 'compressor' |\n 'delay' |\n 'envelopegenerator' |\n 'equalizer' |\n 'filter' |\n 'flanger' |\n 'fuzz' |\n 'listener' |\n 'noisegate' |\n 'noisesuppressor' |\n 'overdrive' |\n 'panner' |\n 'phaser' |\n 'pitchshifter' |\n 'preamp' |\n 'reverb' |\n 'ringmodulator' |\n 'stereo' |\n 'tremolo' |\n 'vocalcanceler' |\n 'wah';\n\nexport type SoundModuleParams = {\n mastervolume?: number,\n autopanner?: AutopannerParams,\n bitcrusher?: BitCrusherParams,\n chorus?: ChorusParams,\n compressor?: CompressorParams,\n delay?: DelayParams,\n envelopegenerator?: EnvelopeGeneratorParams,\n equalizer?: EqualizerParams,\n filter?: FilterParams,\n flanger?: FlangerParams,\n fuzz?: FuzzParams,\n listener?: ListenerParams,\n noisegate?: NoiseGateParams,\n noisesuppressor?: NoiseSuppressorParams,\n overdrive?: OverDriveParams,\n panner?: PannerParams,\n phaser?: PhaserParams,\n pitchshifter?: PitchShifterParams,\n preamp?: PreampParams,\n reverb?: ReverbParams,\n ringmodulator?: RingmodulatorParams,\n stereo?: StereoParams,\n tremolo?: TremoloParams,\n vocalcanceler?: VocalCancelerParams,\n wah?: WahParams\n};\n\nexport { SoundModuleProcessor };\n\n/**\n * This class is superclass that is the top in this library.\n * This class is extended as subclass (`OscillatorModule`, `OneshotModule`, `NoiseModule`, `AudioModule`, `MediaModule`, `StreamModule`, `ProcessorModule`, `MixerModule` ...etc).\n */\nexport abstract class SoundModule implements Connectable {\n public static readonly NUMBER_OF_INPUTS = 2;\n public static readonly NUMBER_OF_OUTPUTS = 2;\n\n protected context: AudioContext;\n protected destination: AudioDestinationNode | MediaStreamAudioDestinationNode;\n\n protected modules: Connectable[] = [];\n\n protected mastervolume: GainNode;\n protected processor: AudioWorkletNode;\n\n protected analyser: Analyser;\n protected recorder: Recorder;\n\n protected autopanner: Autopanner;\n protected bitcrusher: BitCrusher;\n protected chorus: Chorus;\n protected compressor: Compressor;\n protected delay: Delay;\n protected envelopegenerator: EnvelopeGenerator;\n protected equalizer: Equalizer;\n protected filter: Filter;\n protected flanger: Flanger;\n protected fuzz: Fuzz;\n protected listener: Listener;\n protected noisegate: NoiseGate;\n protected noisesuppressor: NoiseSuppressor;\n protected overdrive: OverDrive;\n protected panner: Panner;\n protected phaser: Phaser;\n protected pitchshifter: PitchShifter;\n protected preamp: Preamp;\n protected reverb: Reverb;\n protected ringmodulator: Ringmodulator;\n protected stereo: Stereo;\n protected tremolo: Tremolo;\n protected vocalcanceler: VocalCanceler;\n protected wah: Wah;\n\n protected runningAnalyser = false;\n protected mixed = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n\n this.destination = context.destination;\n\n this.mastervolume = context.createGain();\n this.processor = new AudioWorkletNode(context, SoundModuleProcessor.name);\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context);\n this.autopanner = new Autopanner(context);\n this.bitcrusher = new BitCrusher(context);\n this.chorus = new Chorus(context);\n this.compressor = new Compressor(context);\n this.delay = new Delay(context);\n this.envelopegenerator = new EnvelopeGenerator(context);\n this.equalizer = new Equalizer(context);\n this.filter = new Filter(context);\n this.flanger = new Flanger(context);\n this.fuzz = new Fuzz(context);\n this.listener = new Listener(context);\n this.noisegate = new NoiseGate(context);\n this.noisesuppressor = new NoiseSuppressor(context);\n this.overdrive = new OverDrive(context);\n this.panner = new Panner(context);\n this.phaser = new Phaser(context);\n this.pitchshifter = new PitchShifter(context);\n this.preamp = new Preamp(context);\n this.reverb = new Reverb(context);\n this.ringmodulator = new Ringmodulator(context);\n this.stereo = new Stereo(context);\n this.tremolo = new Tremolo(context);\n this.vocalcanceler = new VocalCanceler(context);\n this.wah = new Wah(context);\n\n // The default order for connection\n this.modules = [\n this.compressor,\n this.wah,\n this.bitcrusher,\n this.overdrive,\n this.fuzz,\n this.preamp,\n this.equalizer,\n this.filter,\n this.pitchshifter,\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 this.autopanner\n ];\n }\n\n /**\n * This method connects `AudioNode`s.\n * @param {AudioNode} source This argument is `AudioNode` as sound source.\n */\n public connect(source: AudioNode): void {\n // Start connection\n // AudioSourceNode (Input)-> AudioNode -> ... -> AudioNode -> GainNode (Master Volume) -> AnalyserNode -> AudioDestinationNode (Output)\n source.disconnect(0); // Clear connection\n\n if (this.modules.length > 0) {\n const input = this.modules[0].INPUT;\n\n if (input === null) {\n return;\n }\n\n source.connect(input);\n } else {\n source.connect(this.mastervolume);\n }\n\n for (let i = 0, len = this.modules.length; i < len; i++) {\n const output = this.modules[i].OUTPUT;\n\n if (output === null) {\n continue;\n }\n\n // Clear connection\n output.disconnect(0);\n\n if (i < (this.modules.length - 1)) {\n const input = this.modules[i + 1].INPUT;\n\n if (input === null) {\n continue;\n }\n\n // Connect to next `AudioNode`\n output.connect(input);\n } else {\n output.connect(this.mastervolume);\n }\n }\n\n this.mastervolume.connect(this.destination);\n\n // for analyser\n this.mastervolume.connect(this.analyser.INPUT);\n\n // for recorder\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.OUTPUT.connect(this.destination);\n }\n\n /**\n * This method disconnects instance of `AudioWorkletNode` as sound source.\n */\n public disconnect(): void {\n this.processor.disconnect(0);\n }\n\n /**\n * This method switches destination over to `AudioDestinationNode`.\n * @return {SoundModule} Return value is for method chain.\n */\n public audioDestination() {\n this.destination = this.context.destination;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method switches destination over to `MediaStreamAudioDestinationNode`.\n * @property {string} sinkId This argument is string as output device ID.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @return {SoundModule} Return value is for method chain.\n */\n public streamDestination(params?: {\n sinkId: string;\n successCallback?: () => void;\n errorCallback?: (error: Error) => void;\n }) {\n this.destination = this.context.createMediaStreamDestination();\n\n if (params?.sinkId) {\n const { sinkId, successCallback, errorCallback } = params;\n\n this.setSinkId(sinkId, successCallback, errorCallback);\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method enables to use multiple output devices.\n * @param {string} sinkId This argument is string as output device ID.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {SoundModule} Return value is for method chain.\n */\n public setSinkId(sinkId: string, successCallback?: () => void, errorCallback?: (error: Error) => void) {\n // @ts-expect-error It is possible that `setSinkId` method is not implemented\n if (this.context.setSinkId) {\n // @ts-expect-error It is possible that `setSinkId` method is not implemented\n this.context.setSinkId(sinkId)\n .then(() => {\n if (typeof successCallback === 'function') {\n successCallback();\n }\n })\n .catch((error: Error) => {\n if (typeof errorCallback === 'function') {\n errorCallback(error);\n }\n });\n }\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method installs customized effector.\n * @param {Effector} effector This argument is subclass that extends `Effector` class.\n * @return {Effector} Return value is instance of customized effector (that extends `Effector` class).\n */\n public install<ExtendedEffector extends Effector>(effector: new (context: AudioContext) => ExtendedEffector): ExtendedEffector {\n const extendedEffector = new effector(this.context);\n\n this.modules.push(extendedEffector);\n\n return extendedEffector;\n }\n\n /**\n * This method starts effectors.\n * @param {number} startTime This argument is used for scheduling parameter.\n * @return {SoundModule} Return value is for method chain.\n */\n public on(startTime?: number) {\n const s = startTime ?? this.context.currentTime;\n\n this.autopanner.start(s);\n this.bitcrusher.start(s);\n this.chorus.start(s);\n this.filter.start(s);\n this.flanger.start(s);\n this.fuzz.start(s);\n this.overdrive.start(s);\n this.phaser.start(s);\n this.ringmodulator.start(s);\n this.tremolo.start(s);\n this.wah.start(s);\n\n // Type inference every subclass\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} Return value is for method chain.\n */\n public off(stopTime?: number) {\n const s = stopTime ?? this.context.currentTime;\n\n this.autopanner.stop(s);\n this.bitcrusher.stop(s);\n this.chorus.stop(s);\n this.filter.stop(s);\n this.flanger.stop(s);\n this.fuzz.stop(s);\n this.overdrive.stop(s);\n this.phaser.stop(s);\n this.ringmodulator.stop(s);\n this.tremolo.stop(s);\n this.wah.stop(s);\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method stops analyser, recorder and `onaudioprocess` event.\n * @return {SoundModule} Return value is for method chain.\n */\n public suspend() {\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n this.runningAnalyser = false;\n\n this.recorder.stop();\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method is invoked on mixing.\n * @return {SoundModule} Return value is for method chain.\n */\n public mix() {\n this.mixed = true;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method is invoked on demixing.\n * @return {SoundModule} Return value is for method chain.\n */\n public demix() {\n this.mixed = false;\n\n // Type inference every subclass\n return this;\n }\n\n /**\n * This method gets effector's parameters as associative array.\n * @return {SoundModuleParams}\n */\n public params(): Required<SoundModuleParams> {\n return {\n mastervolume : this.mastervolume.gain.value,\n stereo : this.stereo.params(),\n compressor : this.compressor.params(),\n bitcrusher : this.bitcrusher.params(),\n overdrive : this.overdrive.params(),\n fuzz : this.fuzz.params(),\n preamp : this.preamp.params(),\n wah : this.wah.params(),\n pitchshifter : this.pitchshifter.params(),\n equalizer : this.equalizer.params(),\n filter : this.filter.params(),\n autopanner : this.autopanner.params(),\n tremolo : this.tremolo.params(),\n ringmodulator : this.ringmodulator.params(),\n phaser : this.phaser.params(),\n flanger : this.flanger.params(),\n chorus : this.chorus.params(),\n delay : this.delay.params(),\n reverb : this.reverb.params(),\n panner : this.panner.params(),\n listener : this.listener.params(),\n envelopegenerator: this.envelopegenerator.params(),\n noisegate : this.noisegate.params(),\n noisesuppressor : this.noisesuppressor.params(),\n vocalcanceler : this.vocalcanceler.params()\n };\n }\n\n /**\n * This method edits module to use and module connection order.\n * @param {Array<Connectable>} modules This argument is edited modules.\n * @return {Array<Connectable>} Return value is previous modules.\n */\n public edit(modules: Connectable[]): Connectable[] {\n const previousModules = this.modules;\n\n this.modules = modules;\n\n return previousModules;\n }\n\n /**\n * This method gets effector's parameters as JSON.\n * @return {string}\n */\n public toJSON(): string {\n return JSON.stringify(this.params());\n }\n\n /**\n * Connector for input.\n */\n public abstract get INPUT(): GainNode | AudioWorkletNode | null;\n\n /**\n * Connector for output.\n */\n public abstract get OUTPUT(): GainNode;\n\n /**\n * This method re-initials modules.\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n protected init(context: AudioContext): void {\n this.mastervolume.disconnect(0);\n this.processor.disconnect(0);\n this.analyser.INPUT.disconnect(0);\n this.recorder.INPUT.disconnect(0);\n\n for (const module of this.modules) {\n if (module.INPUT) {\n module.INPUT.disconnect(0);\n }\n\n if (module.OUTPUT) {\n module.OUTPUT.disconnect(0);\n }\n }\n\n this.modules.length = 0;\n\n this.analyser = new Analyser(context);\n this.recorder = new Recorder(context);\n this.autopanner = new Autopanner(context);\n this.bitcrusher = new BitCrusher(context);\n this.chorus = new Chorus(context);\n this.compressor = new Compressor(context);\n this.delay = new Delay(context);\n this.envelopegenerator = new EnvelopeGenerator(context);\n this.equalizer = new Equalizer(context);\n this.filter = new Filter(context);\n this.flanger = new Flanger(context);\n this.fuzz = new Fuzz(context);\n this.listener = new Listener(context);\n this.noisegate = new NoiseGate(context);\n this.noisesuppressor = new NoiseSuppressor(context);\n this.overdrive = new OverDrive(context);\n this.panner = new Panner(context);\n this.phaser = new Phaser(context);\n this.pitchshifter = new PitchShifter(context);\n this.preamp = new Preamp(context);\n this.reverb = new Reverb(context);\n this.ringmodulator = new Ringmodulator(context);\n this.stereo = new Stereo(context);\n this.tremolo = new Tremolo(context);\n this.vocalcanceler = new VocalCanceler(context);\n this.wah = new Wah(context);\n\n // The default order for connection\n this.modules = [\n this.compressor,\n this.wah,\n this.bitcrusher,\n this.overdrive,\n this.fuzz,\n this.preamp,\n this.equalizer,\n this.filter,\n this.pitchshifter,\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 this.autopanner\n ];\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class OscillatorModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { Statable } from '../interfaces';\n\nexport type GlideType = 'linear' | 'exponential';\n\nexport type GlideParams = {\n state?: boolean,\n type?: GlideType,\n time?: number\n};\n\n/**\n * This private class is for oscillator glide.\n */\nexport class Glide implements Statable {\n private context: AudioContext;\n\n private type: GlideType = 'linear';\n\n private time = 0; // Glide time\n\n private prevFrequency = -1; // Abnormal value (for the 1st sound)\n private nextFrequency = 0;\n\n private isActive = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n this.context = context;\n }\n\n /**\n * This method sets frequencies for glide.\n * @param {number} frequency This argument is next frequency for glide.\n */\n public ready(frequency: number): void {\n this.nextFrequency = frequency;\n\n const diff = (this.prevFrequency === -1) ? 0 : (this.nextFrequency - this.prevFrequency);\n\n if (!this.isActive || (this.time === 0) || (diff === 0)) {\n // The 1st sound or Glide OFF or The same sound\n this.prevFrequency = this.nextFrequency;\n }\n }\n\n /**\n * This method starts glide.\n * @param {OscillatorNode} oscillator This argument is instance of `OscillatorNode`.\n * @param {number} startTime This argument is start time for glide.\n */\n public start(oscillator: OscillatorNode, startTime?: number): void {\n const t0 = startTime ?? this.context.currentTime;\n const t1 = t0 + this.time;\n\n // Start glide\n oscillator.frequency.cancelScheduledValues(t0);\n oscillator.frequency.setValueAtTime(this.prevFrequency, t0);\n\n if (this.type === 'exponential') {\n oscillator.frequency.exponentialRampToValueAtTime(this.nextFrequency, t1);\n } else {\n oscillator.frequency.linearRampToValueAtTime(this.nextFrequency, t1);\n }\n }\n\n /**\n * This method stops glide. Moreover, This method prepares for next glide.\n */\n public stop(): void {\n // Stop glide or on the way of glide\n this.prevFrequency = this.nextFrequency;\n }\n\n /**\n * This method gets or sets parameters for glide.\n * @param {keyof GlideParams|GlideParams} params This argument is string if getter. Otherwise, setter.\n * @return {GlideParams[keyof GlideParams]|Glide} Return value is parameter for glide if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): GlideType;\n public param(params: 'time'): number;\n public param(params: GlideParams): Glide;\n public param(params: keyof GlideParams | GlideParams): GlideParams[keyof GlideParams] | Glide {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.type;\n }\n\n case 'time': {\n return this.time;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.type = value;\n }\n\n break;\n }\n\n case 'time': {\n if (typeof value === 'number') {\n this.time = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets glide parameters as associative array.\n * @return {GlideParams}\n */\n public params(): Required<GlideParams> {\n return {\n state: this.isActive,\n type : this.type,\n time : this.time\n };\n }\n\n /**\n * This method gets glide state. If returns `true`, glide is active.\n * @return {boolean}\n */\n public state(): boolean {\n return this.isActive;\n }\n\n /**\n * This method activates glide.\n * @return {Glide} Return value is for method chain.\n */\n public activate(): Glide {\n this.isActive = true;\n return this;\n }\n\n /**\n * This method deactivates glide.\n * @return {Glide} Return value is for method chain.\n */\n public deactivate(): Glide {\n this.isActive = false;\n return this;\n }\n}\n","import type { Connectable, Statable } from '../interfaces';\n\nexport type OscillatorCustomType = {\n real: Float32Array,\n imag: Float32Array\n};\n\nexport type OscillatorParams = {\n state?: boolean,\n type?: OscillatorType | OscillatorCustomType,\n octave?: number,\n fine?: number,\n volume?: number\n};\n\n/**\n * This private class is entity for oscillator.\n */\nexport class Oscillator implements Connectable, Statable {\n // 1 Octave = 1200 cent\n public static readonly OCTAVE = 1200 as const;\n\n private context: AudioContext;\n private source: OscillatorNode;\n private volume: GainNode;\n\n private octave = 0;\n private fine = 0;\n private custom: OscillatorCustomType = {\n real: new Float32Array([0, 1]),\n imag: new Float32Array([0, 1])\n };\n\n private isActive: boolean;\n\n // in order to not call in duplicate `start` or `stop` method in instance of `OscillatorNode`\n private paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n * @param {boolean} state This argument is initial state.\n */\n constructor(context: AudioContext, state: boolean) {\n this.context = context;\n this.source = context.createOscillator();\n this.volume = context.createGain();\n\n this.isActive = state;\n }\n\n /**\n * This method connects `AudioNode`s.\n * @param {AudioNode} output This argument is instance of `AudioNode` as output.\n */\n public ready(output: AudioNode): void {\n if (!this.isActive) {\n return;\n }\n\n // Store parameters\n const type = this.source.type;\n const frequency = this.source.frequency.value;\n const detune = this.source.detune.value;\n\n if (!this.paused) {\n this.source.stop(this.context.currentTime);\n this.source.disconnect(0);\n }\n\n this.source = this.context.createOscillator();\n\n if (type === 'custom') {\n // Custom wave\n const reals = this.custom.real;\n const imags = this.custom.imag;\n const periodicWave = this.context.createPeriodicWave(reals, imags);\n\n this.source.setPeriodicWave(periodicWave);\n } else {\n this.source.type = type;\n }\n\n this.source.frequency.value = frequency;\n this.source.detune.value = detune;\n\n this.volume.connect(output);\n }\n\n /**\n * This method starts sound.\n * @param {number} startTime This argument is start time.\n */\n public start(startTime?: number): void {\n if (this.isActive) {\n this.source.start(startTime ?? this.context.currentTime);\n this.paused = false;\n } else {\n if (!this.paused) {\n this.source.stop(this.context.currentTime);\n this.paused = true;\n }\n\n this.source.disconnect(0);\n }\n }\n\n /**\n * This method stops sound.\n * @param {number} stopTime This argument is stop time.\n */\n public stop(stopTime?: number): void {\n if (this.paused) {\n return;\n }\n\n this.source.stop(stopTime ?? this.context.currentTime);\n this.source.disconnect(0);\n\n this.paused = true;\n }\n\n /**\n * This method gets or sets parameters for oscillator.\n * @param {keyof OscillatorParams|OscillatorParams} params This argument is string if getter. Otherwise, setter.\n * @return {OscillatorParams[keyof OscillatorParams]} Return value is parameter for oscillator if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'state'): boolean;\n public param(params: 'type'): OscillatorType | OscillatorCustomType;\n public param(params: 'octave'): number;\n public param(params: 'fine'): number;\n public param(params: 'volume'): number;\n public param(params: OscillatorParams): Oscillator;\n public param(params: keyof OscillatorParams | OscillatorParams): OscillatorParams[keyof OscillatorParams] | Oscillator {\n if (typeof params === 'string') {\n switch (params) {\n case 'state': {\n return this.isActive;\n }\n\n case 'type': {\n return this.source.type;\n }\n\n case 'octave': {\n return this.octave;\n }\n\n case 'fine': {\n return this.fine;\n }\n\n case 'volume': {\n return this.volume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'state': {\n if (typeof value === 'boolean') {\n this.isActive = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n this.source.type = value;\n } else if (typeof value === 'object') {\n let { real, imag } = value;\n\n const MAX_SIZE = 4096; // This size is defined by specification\n\n if (real.length > MAX_SIZE) { real = real.subarray(0, MAX_SIZE); }\n if (imag.length > MAX_SIZE) { imag = imag.subarray(0, MAX_SIZE); }\n\n // The 1st value is fixed by 0 (This is is defined by specification)\n if (real[0] !== 0) { real[0] = 0; }\n if (imag[0] !== 0) { imag[0] = 0; }\n\n const periodicWave = this.context.createPeriodicWave(real, imag);\n\n this.source.setPeriodicWave(periodicWave);\n\n this.custom.real = real;\n this.custom.imag = imag;\n }\n\n break;\n }\n\n case 'octave': {\n if (typeof value === 'number') {\n this.octave = value;\n this.source.detune.value = this.fine + (value * Oscillator.OCTAVE);\n }\n\n break;\n }\n\n case 'fine': {\n if (typeof value === 'number') {\n this.fine = value;\n this.source.detune.value = value + (this.octave * Oscillator.OCTAVE);\n }\n\n break;\n }\n\n case 'volume': {\n if (typeof value === 'number') {\n this.volume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `OscillatorNode`.\n * @return {OscillatorNode}\n */\n public get(): OscillatorNode {\n return this.source;\n }\n\n /** @override */\n public state(): boolean {\n return this.isActive;\n }\n\n /** @override */\n public activate(): Oscillator {\n this.isActive = true;\n return this;\n }\n\n /** @override */\n public deactivate(): Oscillator {\n this.isActive = false;\n return this;\n }\n\n /**\n * This method gets oscillator parameters as associative array.\n * @return {OscillatorParams}\n */\n public params(): Required<OscillatorParams> {\n return {\n state : this.isActive,\n type : this.source.type,\n octave: this.octave,\n fine : this.fine,\n volume: this.volume.gain.value\n };\n }\n\n /** @override */\n public get INPUT(): OscillatorNode {\n return this.source;\n }\n\n /** @override */\n public get OUTPUT(): GainNode {\n return this.volume;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { OscillatorParams, OscillatorCustomType } from './Oscillator';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\nimport type { GlideParams, GlideType } from './Glide';\n\nimport { SoundModule } from '../SoundModule';\nimport { OscillatorModuleProcessor } from './OscillatorModuleProcessor';\nimport { Glide } from './Glide';\nimport { Oscillator } from './Oscillator';\n\nexport type {\n Glide,\n GlideParams,\n GlideType,\n Oscillator,\n OscillatorParams,\n OscillatorCustomType\n};\n\nexport { OscillatorModuleProcessor };\n\nexport type OscillatorModuleParams = SoundModuleParams & {\n oscillator?: {\n glide: GlideParams,\n params: OscillatorParams[]\n }\n};\n\n/**\n * This class manages instances of `Oscillator` for creating sound.\n */\nexport class OscillatorModule extends SoundModule {\n private sources: Oscillator[] = [];\n private glide: Glide;\n\n private startTime = 0;\n private duration = 0;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, OscillatorModuleProcessor.name);\n this.glide = new Glide(context);\n }\n\n /**\n * This method creates instances of `Oscillator`.\n * @param {Array<boolean>} states This argument is array that contains initial state in instance of `Oscillator`.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public setup(states: boolean[]): OscillatorModule {\n // Clear\n this.sources.length = 0;\n\n for (let i = 0, len = states.length; i < len; i++) {\n this.sources[i] = new Oscillator(this.context, states[i]);\n this.envelopegenerator.setGenerator(i);\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 start time. The default value is `currentTime` in instance of `AudioContext`\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public ready(startTime?: number, duration?: number): OscillatorModule {\n this.startTime = startTime ?? this.context.currentTime;\n this.duration = duration ?? 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>} frequencies This argument each oscillator frequency. The default value is 0 Hz.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public start(frequencies: number[]): OscillatorModule {\n const startTime = this.context.currentTime + this.startTime;\n\n if (!this.mixed) {\n // Clear previous\n this.envelopegenerator.clear(true);\n\n // AudioWorkletNode (Mix oscillators) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n }\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) -> AudioWorkletNode (Mix oscillators)\n oscillator.ready(this.processor);\n\n // OscillatorNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume)\n this.envelopegenerator.ready(i, oscillator.INPUT, oscillator.OUTPUT);\n\n this.glide.ready(frequency);\n this.glide.start(oscillator.INPUT, 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.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method stops active sounds.\n * @return {OscillatorModule} Return value is for method chain.\n */\n public stop(): OscillatorModule {\n const stopTime = this.context.currentTime + this.startTime + this.duration;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime, false);\n\n this.glide.stop();\n this.filter.stop(stopTime);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for oscillator module.\n * This method is overloaded for type interface and type check.\n * @param {keyof OscillatorModuleParams|OscillatorModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {OscillatorModuleParams[keyof OscillatorModuleParams]|OscillatorModule} Return value is parameter for oscillator module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: OscillatorModuleParams): OscillatorModule;\n public param(params: keyof OscillatorModuleParams | OscillatorModuleParams): OscillatorModuleParams[keyof OscillatorModuleParams] | OscillatorModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Oscillator` or array that contains the all of `Oscillator`s.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `Oscillator`.\n * @return {Oscillator|Array<Oscillator>}\n */\n public get(index: number): Oscillator;\n public get(): Oscillator[];\n public get(index?: number): Oscillator | Oscillator[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.sources.length)) {\n return this.sources[index];\n }\n\n return this.sources;\n }\n\n /**\n * This method returns the number of `Oscillator`s.\n * @return {number}\n */\n public length(): number {\n return this.sources.length;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName|'glide'} moduleName This argument selects module.\n * @return {Module|Glide}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: 'glide'): Glide;\n public module(moduleName: ModuleName | 'glide'): Module | Glide {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n\n case 'glide': {\n return this.glide;\n }\n }\n }\n\n /**\n * This method gets oscillator module parameters as associative array.\n * @return {OscillatorModuleParams}\n * @override\n */\n public override params(): Required<OscillatorModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n oscillator: {\n glide : this.glide.params(),\n params: this.sources.map((source: Oscillator) => {\n return source.params();\n })\n }\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class OneshotModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { OneshotModuleProcessor } from './OneshotModuleProcessor';\n\nexport type OneshotErrorText = 'error' | 'timeout' | 'decode';\n\nexport type OneshotSetting = {\n bufferIndex: number,\n playbackRate?: number,\n loop?: boolean,\n loopStart?: number,\n loopEnd?: number,\n volume?: number\n};\n\nexport type OneshotSettings = OneshotSetting[];\n\nexport type OneshotModuleParams = SoundModuleParams & {\n transpose?: number\n};\n\nexport { OneshotModuleProcessor };\n\n/**\n * This subclass is for playing one-shot audio\n */\nexport class OneshotModule extends SoundModule {\n private sources: AudioBufferSourceNode[] = [];\n private resources: string[] | AudioBuffer[] = [];\n private buffers: AudioBuffer[] = [];\n private volumes: GainNode[] = [];\n private states: boolean[] = [];\n private settings: OneshotSettings = [];\n\n private startTime = 0;\n private duration = 0;\n\n private transpose = 0;\n\n // If error occurs at least one, this method aborts the all of connections.\n // Therefore, this flag are shared with the all of `XMLHttpRequest` instances.\n private loadError = false;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, OneshotModuleProcessor.name);\n }\n\n /**\n * This method creates instances of `AudioBuffer` by Ajax.\n * @property {Array<string>|Array<AudioBuffer>} resources This argument is array that contains URL or instance of `AudioBuffer` for audio resources.\n * @property {OneshotSettings} settings This argument is settings (such as `playbackRate`, `loop` ... etc) each audio sources.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success;\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n * @property {OneshotModule} Return value is for method chain.\n */\n public setup(params: {\n resources: string[] | AudioBuffer[];\n settings: OneshotSettings;\n timeout?: number;\n successCallback?(event: ProgressEvent, buffers: AudioBuffer[]): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: OneshotErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): OneshotModule {\n const { resources, settings, timeout, successCallback, errorCallback, progressCallback } = params;\n\n for (let i = 0, len = settings.length; i < len; i++) {\n this.states[i] = false;\n this.volumes[i] = this.context.createGain();\n this.settings[i] = settings[i];\n\n this.envelopegenerator.setGenerator(i);\n }\n\n for (let index = 0, len = resources.length; index < len; index++) {\n this.resources[index] = resources[index];\n\n const url = this.resources[index];\n\n if (typeof url === 'string') {\n // Get instance of `AudioBuffer` from designated URL.\n this.load({ url, index, timeout, successCallback, errorCallback, progressCallback });\n } else {\n this.buffers[index] = url;\n }\n }\n\n return this;\n }\n\n /**\n * This method schedules playing audio.\n * @param {number} startTime This argument is start time. The default value is 0.\n * @param {number} duration This argument is duration. The default value is 0.\n * @return {OneshotModule} Return value is for method chain.\n */\n public ready(startTime?: number, duration?: number): OneshotModule {\n this.startTime = startTime ?? 0;\n this.duration = duration ?? 0;\n\n this.envelopegenerator.clear(false);\n\n return this;\n }\n\n /**\n * This method starts one-shot audio.\n * @param {Array<number>} indexes This argument selects instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} Return value is for method chain.\n */\n public start(indexes: number[]): OneshotModule {\n const startTime = this.context.currentTime + this.startTime;\n\n if (!this.mixed) {\n this.envelopegenerator.clear(false);\n\n // AudioWorkletNode (Mix one-shots) -> ... -> AudioDestinationNode (Output)\n this.connect(this.processor);\n }\n\n for (const index of indexes) {\n if ((index < 0) || (index >= this.settings.length)) {\n continue;\n }\n\n const { bufferIndex, playbackRate, loop, loopStart, loopEnd, volume } = this.settings[index];\n\n // The following code is unnecessary, because `AudioBufferSourceNode` is the target of garbage collection in case of no references and no sound\n // (If there is this code, application cannot repeat hits).\n\n // if (this.sources[index]) {\n // this.sources[index].stop(this.context.currentTime);\n // this.sources[index].disconnect(0);\n // }\n\n const source = this.context.createBufferSource();\n\n source.buffer = this.buffers[bufferIndex];\n\n source.playbackRate.value = playbackRate ?? 1;\n source.detune.value = this.transpose * 100;\n source.loop = loop ?? false;\n source.loopStart = loopStart ?? 0;\n source.loopEnd = loopEnd ?? source.buffer.duration;\n\n this.volumes[index].gain.value = volume ?? 1;\n\n // AudioBufferSourceNode (Input) -> GainNode (Envelope Generator) -> GainNode (Volume) -> AudioWorkletNode (Mix one-shots)\n this.envelopegenerator.ready(index, source, this.volumes[index]);\n this.volumes[index].connect(this.processor);\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[index] = source;\n\n this.states[index] = true;\n }\n\n // Attack -> Decay -> Sustain\n this.envelopegenerator.start(startTime);\n\n this.on(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method stops one-shot audio.\n * @param {Array<number>} indexes This argument selects instance of `AudioBufferSourceNode`.\n * @return {OneshotModule} Return value is for method chain.\n */\n public stop(indexes: number[]): OneshotModule {\n const stopTime = this.context.currentTime + this.startTime + this.duration;\n\n indexes.forEach((index: number) => {\n if (this.states[index]) {\n this.sources[index].stop(stopTime);\n\n this.states[index] = false;\n }\n });\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n this.envelopegenerator.clear(false);\n\n this.off(stopTime);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for one-shot module.\n * This method is overloaded for type interface and type check.\n * @param {keyof OneshotModuleParams|OneshotModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {OneshotModuleParams[keyof OneshotModuleParams]|OneshotModule} Return value is parameter for one-shot module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'transpose'): number;\n public param(params: OneshotModuleParams): OneshotModule;\n public param(params: keyof OneshotModuleParams | OneshotModuleParams): OneshotModuleParams[keyof OneshotModuleParams] | OneshotModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'transpose': {\n return this.transpose;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'transpose': {\n if (typeof value === 'number') {\n this.transpose = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AudioBuffer` or array that contains the all of `AudioBuffer`s.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `AudioBuffer`.\n * @return {AudioBuffer|AudioBuffer[]}\n */\n public get(index: number): AudioBuffer;\n public get(): AudioBuffer[];\n public get(index?: number): AudioBuffer | AudioBuffer[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.buffers.length)) {\n return this.buffers[index];\n }\n\n return this.buffers;\n }\n\n /**\n * This method resets settings.\n * @param {number} index This argument selects target setting.\n * @param {keyof OneshotSetting} paramName This argument is one-shot parameter name.\n * @param {OneshotSetting} param This argument is one-shot parameter value.\n * @return {OneshotModule} Return value is for method chain.\n */\n public reset(index: number, paramName: keyof OneshotSetting, param: number | boolean): OneshotModule {\n if ((index >= 0) && (index < this.settings.length)) {\n switch (paramName) {\n case 'bufferIndex' :\n case 'playbackRate':\n case 'loopStart' :\n case 'loopEnd' :\n case 'volume' : {\n if (typeof param === 'number') {\n this.settings[index][paramName] = param;\n }\n\n break;\n }\n\n case 'loop': {\n if (typeof param === 'boolean') {\n this.settings[index][paramName] = param;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets one-shot module parameters as associative array.\n * @return {OneshotModuleParams}\n * @override\n */\n public override params(): Required<OneshotModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n transpose: this.transpose\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method gets `ArrayBuffer` and creates instance of `AudioBuffer`.\n * @property {string} url This argument is resource URL for one-shot audio.\n * @property {number} index This argument is in order to assign instance of `AudioBuffer`.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success;\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving audio data.\n */\n private load(params: {\n url: string;\n index: number;\n timeout?: number;\n successCallback?(event: ProgressEvent, buffers: AudioBuffer[]): void;\n errorCallback?(event: ProgressEvent | Error, textStatus: OneshotErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n }): void {\n const { url, index, timeout, successCallback, errorCallback, progressCallback } = params;\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'timeout');\n }\n\n this.loadError = true;\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (this.loadError) {\n xhr.abort();\n } else if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (!this.loadError && errorCallback) {\n errorCallback(event, 'error');\n }\n\n this.loadError = true;\n };\n\n // Success\n xhr.onload = (event: ProgressEvent) => {\n if (xhr.status === 200) {\n const arrayBuffer = xhr.response;\n\n if (!(arrayBuffer instanceof ArrayBuffer)) {\n return;\n }\n\n const decodeSuccessCallback = (buffer: AudioBuffer) => {\n this.buffers[index] = buffer;\n\n // Creating instance of `AudioBuffer` has completed ?\n for (const buffer of this.buffers) {\n if (buffer === undefined) {\n return;\n }\n }\n\n if (successCallback) {\n successCallback(event, this.buffers);\n }\n };\n\n const decodeErrorCallback = (error: Error) => {\n if (errorCallback) {\n errorCallback(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';\n xhr.send(null);\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\nimport type { NoiseType, NoiseModuleParams } from './';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\ninterface NoiseModuleProcessorWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n whitenoise: (frame: number) => number;\n pinknoise: (frame: number) => number;\n browniannoise: (frame: number) => number;\n};\n\nexport type NoiseProcessingMessageEventData = {\n processing?: boolean;\n};\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for generating noise.\n */\nexport class NoiseModuleProcessor extends AudioWorkletProcessor {\n private instance: WebAssembly.Instance | null = null;\n\n private processing = false;\n\n private type: NoiseType = 'whitenoise';\n\n constructor() {\n super();\n\n this.port.onmessage = (event: MessageEvent<ArrayBuffer | (NoiseModuleParams & NoiseProcessingMessageEventData)>) => {\n if (event.data instanceof ArrayBuffer) {\n WebAssembly.instantiate(event.data)\n .then(({ instance }) => {\n this.instance = instance;\n })\n .catch((error: Error) => {\n throw error;\n });\n } else {\n if (typeof event.data.processing === 'boolean') {\n this.processing = event.data.processing;\n }\n\n if (event.data.type) {\n this.type = event.data.type;\n }\n }\n };\n }\n\n /** @override */\n protected override process(_inputs: Inputs, outputs: Outputs): boolean {\n if (this.instance === null) {\n return false;\n }\n\n if (!this.processing) {\n // Prevent from calling private method for noise processor if not active\n return true;\n }\n\n const output = outputs[0];\n\n // HACK:\n const wasm = this.instance.exports as NoiseModuleProcessorWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n for (let channelNumber = 0, numberOfChannels = output.length; channelNumber < numberOfChannels; channelNumber++) {\n const bufferSize = output[channelNumber].length;\n\n switch (this.type) {\n case 'whitenoise': {\n const offsetOutput = wasm.whitenoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n\n case 'pinknoise': {\n const offsetOutput = wasm.pinknoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n\n case 'browniannoise': {\n const offsetOutput = wasm.browniannoise(currentFrame);\n\n output[channelNumber].set(new Float32Array(linearMemory, offsetOutput, bufferSize));\n break;\n }\n }\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { NoiseProcessingMessageEventData } from './NoiseModuleProcessor';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { NoiseModuleProcessor } from './NoiseModuleProcessor';\n\n// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './WebAssemblyModules/noisegenerator.wasm';\n\nexport type NoiseType = 'whitenoise' | 'pinknoise' | 'browniannoise';\n\nexport type NoiseModuleParams = SoundModuleParams & {\n type?: NoiseType\n};\n\nexport { NoiseModuleProcessor };\n\n/**\n * This subclass is for generating noise.\n */\nexport class NoiseModule extends SoundModule {\n private type: NoiseType = 'whitenoise';\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, NoiseModuleProcessor.name);\n\n this.envelopegenerator.setGenerator(0);\n\n fetch(wasm)\n .then(async (response) => {\n const wasm = await response.arrayBuffer();\n\n this.processor.port.postMessage(wasm);\n })\n .catch((error: Error) => {\n throw error;\n });\n }\n\n /**\n * This method defines noop for the same API.\n */\n public setup(): NoiseModule {\n // Noop\n return this;\n }\n\n /**\n * This method defines noop for the same API.\n */\n public ready(): NoiseModule {\n // Noop\n return this;\n }\n\n /**\n * This method starts noise.\n * @return {NoiseModule} Return value is for method chain.\n */\n public start(): NoiseModule {\n const startTime = this.context.currentTime;\n\n if (!this.mixed) {\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n this.connect(generator);\n }\n }\n\n this.envelopegenerator.ready(0, this.processor, null);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n this.on(startTime);\n\n const message: NoiseProcessingMessageEventData = { processing: true };\n\n this.processor.port.postMessage(message);\n\n return this;\n }\n\n /**\n * This method stops noise.\n * @return {NoiseModule} Return value is for method chain.\n */\n public stop(): NoiseModule {\n const stopTime = this.context.currentTime;\n\n // Attack or Decay or Sustain -> Release\n this.envelopegenerator.stop(stopTime);\n\n this.off(stopTime);\n\n const message: NoiseProcessingMessageEventData = { processing: false };\n\n this.processor.port.postMessage(message);\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for noise module.\n * @param {keyof NoiseModuleParams|NoiseModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {NoiseModuleParams[keyof NoiseModuleParams]|NoiseModule} Return value is parameter for noise module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'type'): NoiseType;\n public param(params: NoiseModuleParams): NoiseModule;\n public param(params: keyof NoiseModuleParams | NoiseModuleParams): NoiseModuleParams[keyof NoiseModuleParams] | NoiseModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'type': {\n return this.type;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'type': {\n if (typeof value === 'string') {\n if ((value === 'whitenoise') || (value === 'pinknoise') || (value === 'browniannoise')) {\n this.type = value;\n\n const message: NoiseModuleParams = { type: value };\n\n this.processor.port.postMessage(message);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override disconnect() {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n generator.disconnect(0);\n }\n }\n\n /**\n * This method gets noise module parameters as associative array.\n * @return {NoiseModuleParams}\n * @override\n */\n public override params(): Required<NoiseModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n type: this.type\n };\n }\n\n /** @override */\n public override get INPUT(): GainNode | null {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n return generator;\n }\n\n return null;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class AudioModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n if ((input.length > 0) && (input[0].length > 0)) {\n if ((currentFrame % 16384) === 0) {\n // Fire `onmessage` event (that main thread has) every `16384` samples\n this.port.postMessage({});\n }\n }\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { AudioModuleProcessor } from './AudioModuleProcessor';\n\nexport type AudioBufferSprite = { [spriteName: string]: AudioBuffer };\n\nexport type AudioModuleParams = SoundModuleParams & {\n playbackRate?: number,\n detune?: number,\n speed?: number,\n loop?: boolean,\n currentTime?: number,\n readonly duration?: number,\n readonly sampleRate?: number,\n readonly numberOfChannels?: number\n};\n\nexport { AudioModuleProcessor };\n\n/**\n * This subclass is for playing single audio.\n * This class enables to create audio player that has higher features than `HTMLAudioElement`.\n * But, this class is disadvantage to play many one shot audios.\n * In that case, developer should use `OneshotModule`.\n */\nexport class AudioModule extends SoundModule {\n private source: AudioBufferSourceNode;\n private buffer: AudioBuffer | null = null;\n\n private currentTime = 0;\n private stopped = true;\n\n private speed = 1;\n\n private decodeCallback?(buffer: AudioBuffer): void;\n private updateCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n private endedCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n private errorCallback?(error: Error): void;\n\n /**\n * @param {AudioContext} context This argument is in order to use the interfaces of Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, AudioModuleProcessor.name);\n\n this.source = context.createBufferSource();\n }\n\n /**\n * This method sets up envelope generator for fade-in and fade-out.\n * @return {AudioModule} Return value is for method chain.\n */\n public setup(callbacks?: {\n decodeCallback?(buffer: AudioBuffer): void;\n updateCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n endedCallback?(source: AudioBufferSourceNode, currentTime: number): void;\n errorCallback?(error: Error): void;\n }): AudioModule {\n const { decodeCallback, updateCallback, endedCallback, errorCallback } = callbacks ?? {};\n\n if (decodeCallback) {\n this.decodeCallback = decodeCallback;\n }\n\n if (updateCallback) {\n this.updateCallback = updateCallback;\n }\n\n if (endedCallback) {\n this.endedCallback = endedCallback;\n }\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\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 decodes instance of `ArrayBuffer` to `ArrayBuffer` or sets instanceof `AudioBuffer`.\n * @param {ArrayBuffer|AudioBuffer} buffer This argument is instance of `ArrayBuffer` or `AudioBuffer`.\n * If this is `ArrayBuffer`, this method executes decode.\n * @return {AudioModule} Return value is for method chain.\n */\n public ready(buffer: ArrayBuffer | AudioBuffer): AudioModule {\n if (buffer instanceof ArrayBuffer) {\n this.buffer = null;\n\n const successCallback = (audiobuffer: AudioBuffer) => {\n this.buffer = audiobuffer;\n\n this.analyser.start('timeoverview', 0, this.buffer);\n this.analyser.start('timeoverview', 1, this.buffer);\n\n if (this.decodeCallback) {\n this.decodeCallback(this.buffer);\n }\n };\n\n this.context.decodeAudioData(buffer, successCallback, this.errorCallback);\n } else if (buffer instanceof AudioBuffer) {\n this.buffer = buffer;\n }\n\n return this;\n }\n\n /**\n * This method starts audio from designated time.\n * @param {number} startTime This argument is time that audio is started at. The default value is `0`.\n * @param {number} endTime This argument is time that audio is ended at. The default value is audio duration.\n * @return {AudioModule} This is returned for method chain.\n */\n public start(startTime?: number, endTime?: number): AudioModule {\n if ((this.buffer === null) || !this.stopped) {\n return this;\n }\n\n const currentTime = this.context.currentTime;\n\n const start = startTime ?? 0;\n const end = endTime ?? this.buffer.duration;\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 detune = this.source.detune.value;\n const loop = this.source.loop;\n\n this.source = this.context.createBufferSource();\n\n this.source.buffer = this.buffer;\n this.source.playbackRate.value = playbackRate;\n this.source.detune.value = detune;\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) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor);\n\n const computedPlaybackRate = this.computePlaybackRate();\n\n 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', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.stopped = false;\n\n this.envelopegenerator.start(currentTime);\n\n if (end >= 0) {\n this.envelopegenerator.stop((currentTime + ((end - start) / computedPlaybackRate)), true);\n } else {\n this.envelopegenerator.stop((currentTime + ((this.buffer.duration - start) / computedPlaybackRate)), true);\n }\n\n this.on(currentTime);\n\n const timeoverviewL = this.analyser.domain('timeoverview', 0);\n const timeoverviewR = this.analyser.domain('timeoverview', 1);\n\n // Invoke `onmessage` event handler every `16384` samples and update UI\n this.processor.port.onmessage = () => {\n if (this.buffer === null) {\n this.end();\n return;\n }\n\n if (Math.abs(this.source.loopEnd - this.currentTime) > 0.5) {\n const playbackRate = this.computePlaybackRate();\n\n this.currentTime += ((16384 / this.buffer.sampleRate) * playbackRate);\n\n if (this.updateCallback) {\n this.updateCallback(this.source, this.currentTime);\n }\n\n timeoverviewL.update(this.currentTime);\n timeoverviewR.update(this.currentTime);\n } else {\n if (this.source.loop) {\n this.stop();\n\n if (timeoverviewL.param('mode') === 'sprite') {\n this.start(this.source.loopStart, this.source.loopEnd);\n } else {\n this.start(0, this.buffer.duration);\n }\n } else {\n this.end();\n }\n }\n };\n\n return this;\n }\n\n /**\n * This method stops audio.\n * @return {AudioModule} Return value is for method chain.\n */\n public stop(): AudioModule {\n if ((this.buffer === null) || this.stopped) {\n return this;\n }\n\n const stopTime = this.context.currentTime;\n\n this.source.stop(stopTime);\n\n this.off(stopTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n // Clear\n this.stopped = true;\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for audio module.\n * This method is overloaded for type interface and type check.\n * @param {keyof AudioModuleParams|AudioModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {AudioModuleParams[keyof AudioModuleParams]|AudioModule} Return value is parameter for audio module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'playbackRate'): number;\n public param(params: 'detune'): number;\n public param(params: 'speed'): number;\n public param(params: 'loop'): boolean;\n public param(params: 'currentTime'): number;\n public param(params: 'duration'): number;\n public param(params: 'sampleRate'): number;\n public param(params: 'numberOfChannels'): number;\n public param(params: 'numberOfChannels'): number;\n public param(params: AudioModuleParams): AudioModule;\n public param(params: keyof AudioModuleParams | AudioModuleParams): AudioModuleParams[keyof AudioModuleParams] | AudioModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'playbackRate': {\n return this.source.playbackRate.value;\n }\n\n case 'detune': {\n return this.source.detune.value;\n }\n\n case 'speed': {\n return this.speed;\n }\n\n case 'loop': {\n return this.source.loop;\n }\n\n case 'currentTime': {\n return this.currentTime;\n }\n\n case 'duration': {\n return this.source.buffer?.duration ?? 0; // Getter only\n }\n\n case 'sampleRate': {\n return this.source.buffer?.sampleRate ?? this.context.sampleRate; // Getter only\n }\n\n case 'numberOfChannels': {\n return this.source.buffer?.numberOfChannels ?? 0; // Getter only\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'playbackRate': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.source.playbackRate.value = value;\n\n const playbackRate = this.computePlaybackRate();\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n }\n }\n\n break;\n }\n\n case 'detune': {\n if (typeof value === 'number') {\n this.source.detune.value = value;\n\n const playbackRate = this.computePlaybackRate();\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / playbackRate)), true);\n }\n\n break;\n }\n\n case 'speed': {\n if (typeof value === 'number') {\n if (value > 0) {\n this.speed = value;\n\n const pitch = this.pitchshifter.param('pitch');\n\n this.pitchshifter.param({ pitch: pitch, speed: this.speed });\n\n this.source.playbackRate.value = this.speed;\n\n const startTime = this.context.currentTime;\n const currentTime = this.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n\n this.envelopegenerator.start(startTime);\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / this.speed)), true);\n }\n }\n\n break;\n }\n\n case 'loop': {\n if (typeof value === 'boolean') {\n this.source.loop = value;\n }\n\n break;\n }\n\n case 'currentTime': {\n if (typeof value === 'number') {\n this.currentTime = value;\n\n if (!this.stopped) {\n this.stop();\n this.start(value);\n }\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `AudioBufferSourceNode`.\n * @return {AudioBufferSourceNode}\n */\n public get(): AudioBufferSourceNode {\n return this.source;\n }\n\n /**\n * This method rewinds audio.\n * @return {AudioModule} Return value is for method chain.\n */\n public end(): AudioModule {\n this.stop();\n this.currentTime = 0;\n\n if (this.endedCallback) {\n this.endedCallback(this.source, 0);\n }\n\n return this;\n }\n\n /**\n * This method determines whether instance of `AudioBuffer` exists.\n * @return {boolean} If instance of `AudioBuffer` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.buffer !== null;\n }\n\n /**\n * This method determines whether audio is paused.\n * @return {boolean} If audio is paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return this.stopped;\n }\n\n /**\n * This method gets or sets 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} Return value is fade-in time. Otherwise, return value is for method chain.\n */\n public fadeIn(time?: number): number | AudioModule {\n if (typeof time !== 'number') {\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.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n const playbackRate = this.computePlaybackRate();\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 gets or sets 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} Return value is fade-out time. Otherwise, return value is for method chain.\n */\n public fadeOut(time?: number): number | AudioModule {\n if (typeof time !== 'number') {\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.currentTime;\n const duration = this.source.buffer?.duration ?? 0;\n const playbackRate = this.computePlaybackRate();\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 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} Return value is sliced `AudioBuffer`.\n */\n public slice(startTime?: number, endTime?: number): AudioBuffer | null {\n if (this.buffer === null) {\n return null;\n }\n\n const duration = this.buffer.duration;\n const sampleRate = this.buffer.sampleRate;\n const numberOfChannels = this.buffer.numberOfChannels;\n\n const start = Math.trunc((startTime ?? 0) * sampleRate);\n const end = Math.trunc((endTime ?? duration) * sampleRate);\n\n const dataLs = (numberOfChannels > 0) ? this.buffer.getChannelData(0) : null;\n const dataRs = (numberOfChannels > 1) ? this.buffer.getChannelData(1) : null;\n\n const bufferSize = end - start;\n\n switch (numberOfChannels) {\n case 1: {\n if (dataLs === null) {\n return null;\n }\n\n const bufferLs = new Float32Array(bufferSize);\n\n for (let i = start; i < end; i++) {\n bufferLs[i - start] = dataLs[i];\n }\n\n const buffer = this.context.createBuffer(1, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n\n return buffer;\n }\n\n case 2: {\n if ((dataLs === null) || (dataRs === null)) {\n return null;\n }\n\n const bufferLs = new Float32Array(bufferSize);\n const 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 const buffer = this.context.createBuffer(2, bufferSize, sampleRate);\n\n buffer.copyToChannel(bufferLs, 0);\n buffer.copyToChannel(bufferRs, 1);\n\n return buffer;\n }\n }\n\n return null;\n }\n\n /**\n * This method sprites audio.\n * @param {Object.<string, Array<number>>} sprites This argument is associative array that contains sprite times.\n * @return {AudioBufferSprite} Return value is associative array that contains sprited `AudioBuffer`.\n */\n public sprite(sprites: { [spriteName: string]: [number, number] }): AudioBufferSprite | null {\n if (this.buffer === null) {\n return null;\n }\n\n return Object.keys(sprites).reduce((audioSprite: AudioBufferSprite, spriteName: string) => {\n const times: [number, number] = sprites[spriteName];\n\n const audiobuffer = this.slice(...times);\n\n if (audiobuffer !== null) {\n audioSprite[spriteName] = audiobuffer;\n }\n\n return audioSprite;\n }, {});\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets audio module parameters as associative array.\n * @return {AudioModuleParams}\n * @override\n */\n public override params(): Required<AudioModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n playbackRate : this.source.playbackRate.value,\n detune : this.source.detune.value,\n speed : this.speed,\n loop : this.source.loop,\n currentTime : this.currentTime,\n duration : this.buffer?.duration ?? 0,\n sampleRate : this.buffer?.sampleRate ?? this.context.sampleRate,\n numberOfChannels: this.buffer?.numberOfChannels ?? 0,\n vocalcanceler : this.vocalcanceler.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method returns computed playback rate from `playbackRate` and `detune` that `AudioBufferSourceNode` has (@see https://www.w3.org/TR/webaudio/#computedplaybackrate)\n * @return {number} Return value is computed playback rate.\n */\n private computePlaybackRate(): number {\n return this.source.playbackRate.value * (2 ** (this.source.detune.value / 1200));\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class MediaModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { MediaModuleProcessor } from './MediaModuleProcessor';\n\nexport type MediaModuleParams = SoundModuleParams & {\n autoplay?: boolean,\n playbackRate?: number,\n currentTime?: number,\n controls?: boolean,\n loop?: boolean,\n muted?: boolean,\n readonly duration?: number\n};\n\nexport { MediaModuleProcessor };\n\n/**\n * This class processes sound data from `HTMLMediaElement`.\n * Namely, this class enables to create audio player that has higher features from `HTMLMediaElement`.\n * But, this class is disadvantage to play many one shot audios.\n * In that case, developer should use `OneshotModule`.\n */\nexport class MediaModule extends SoundModule {\n private source: MediaElementAudioSourceNode | null = null;\n private media: HTMLAudioElement | HTMLVideoElement | null = null;\n\n // 'wav', 'ogg', 'mp3, 'webm', 'ogv', 'mp4' ...etc\n private ext = '';\n\n // for Autoplay policy\n private autoplay = false;\n\n // for Audio Streaming\n private mediaSource: MediaSource | null = null;\n private sourceBuffer: SourceBuffer | null = null;\n private file = '';\n private mimeType = '';\n\n // Keys are 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 private listeners: { [eventType: string]: (event: Event | Error) => void } = {};\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, MediaModuleProcessor.name);\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.onSourceBufferUpdateEnd = this.onSourceBufferUpdateEnd.bind(this);\n this.onSourceBufferError = this.onSourceBufferError.bind(this);\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 * @property {HTMLAudioElement|HTMLVideoElement} media This argument is either `HTMLAudioElement` or `HTMLVideoElement`.\n * @property {Array<string>} formats This argument is usable media format. For example, 'wav', 'ogg', 'webm', 'mp4' ...etc.\n * @property {boolean} autoplay This argument is in order to determine autoplay. The default value is `false`.\n * @property {{ [eventType: string]: (event: Event | Error) => void }} listeners This argument is event listeners that are defined by `HTMLMediaElement`.\n * @return {MediaModule} Return value is for method chain.\n */\n public setup(params: {\n media: HTMLAudioElement | HTMLVideoElement;\n formats?: string[];\n autoplay?: boolean;\n listeners?: { [eventType: string]: (event: Event | Error) => void };\n }): MediaModule {\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 const { media, formats, listeners, autoplay } = params;\n\n if (!media) {\n return this;\n }\n\n this.media = media;\n\n for (const format of formats ?? []) {\n const audioMime = `audio/${format}`;\n const videoMime = `video/${format}`;\n\n const canAudio = this.media.canPlayType(audioMime);\n const canVideo = this.media.canPlayType(videoMime);\n\n if (/^(?:maybe|probably)/.test(canAudio) || /^(?:maybe|probably)/.test(canVideo)) {\n this.ext = format;\n break;\n }\n }\n\n if (listeners) {\n this.listeners = listeners;\n\n Object.keys(listeners).forEach((eventType: string) => {\n const listener = listeners[eventType];\n\n if (typeof listener === 'function') {\n listeners[eventType] = listener;\n }\n\n if (this.media) {\n this.media.addEventListener(eventType, listener, false);\n }\n });\n }\n\n this.media.addEventListener('loadstart', () => {\n if (this.media === null) {\n return;\n }\n\n // If the same `HTMLMediaElement`, recreate instance of `MediaElementAudioSourceNode` causes error\n if ((this.source === null) || (this.media !== media)) {\n this.source = this.context.createMediaElementSource(this.media);\n }\n }, false);\n\n this.media.addEventListener('ended', () => {\n if (this.media === null) {\n return;\n }\n\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n }, false);\n\n this.autoplay = autoplay ?? false;\n\n // in case of autoplay, `loadstart` event not fire\n if (this.autoplay && (this.source === null)) {\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 ?? 0);\n })\n .catch((error: Error) => {\n if (this.listeners.error) {\n this.listeners.error(error);\n }\n });\n }\n\n return this;\n }\n\n /**\n * This method prepares for playing media anytime after loading media resource.\n * @param {string} src This argument is Object URL or file name for media resource.\n * @param {string} mimeType This argument is required in case of audio streaming.\n * @return {MediaModule} Return value is for method chain.\n */\n public ready(src: string, mimeType?: string): MediaModule {\n if (this.media === null) {\n return this;\n }\n\n if (this.mediaSource && (this.mediaSource.readyState === 'open')) {\n this.mediaSource.endOfStream();\n window.URL.revokeObjectURL(this.media.src);\n\n this.mediaSource.removeEventListener('sourceopen', this.onSourceOpen, false);\n this.mediaSource.removeEventListener('sourceended', this.onSourceEnded, false);\n this.mediaSource.removeEventListener('sourceclose', this.onSourceClose, false);\n\n if (this.sourceBuffer) {\n this.sourceBuffer.removeEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sourceBuffer.removeEventListener('error', this.onSourceBufferError, false);\n }\n }\n\n if (mimeType) {\n // Audio Streaming\n if (!MediaSource || !MediaSource.isTypeSupported(mimeType)) {\n return this;\n }\n\n this.media.removeAttribute('src');\n\n this.media.load();\n\n this.mediaSource = new MediaSource();\n this.media.src = window.URL.createObjectURL(this.mediaSource);\n this.mimeType = mimeType;\n this.file = src;\n\n this.mediaSource.addEventListener('sourceopen', this.onSourceOpen, false);\n this.mediaSource.addEventListener('sourceended', this.onSourceEnded, false);\n this.mediaSource.addEventListener('sourceclose', this.onSourceClose, false);\n } else if (src.startsWith('blob:') || (this.ext === '')) {\n // Object URL or file name\n this.media.src = src;\n } else {\n // file name (except extension)\n this.media.src = `${src}.${this.ext}`;\n }\n\n return this;\n }\n\n /**\n * This method starts media from designated time.\n * @param {number} position This argument is time that media is started at. The default value is `0`.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {MediaModule} Return value is for method chain.\n */\n public start(position?: number, errorCallback?: (error: Error) => void): MediaModule {\n if ((this.source === null) || (this.media === null)) {\n return this;\n }\n\n // MediaElementAudioSourceNode (Input) -> GainNode (Envelope Generator) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.envelopegenerator.ready(0, this.source, this.processor);\n this.connect(this.processor);\n\n this.media.play()\n .then(() => {\n if (this.media === null) {\n return;\n }\n\n const startTime = this.context.currentTime;\n\n this.media.currentTime = position ?? 0;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(this.media.duration)) {\n this.envelopegenerator.stop((startTime + ((this.media.duration - this.media.currentTime) / this.media.playbackRate)), true);\n }\n\n this.on(startTime);\n\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n })\n .catch(() => {\n this.stop(() => {\n if (this.media === null) {\n return;\n }\n\n if (this.autoplay) {\n this.media.muted = true;\n this.media.volume = 0;\n }\n\n this.start(position);\n }, errorCallback);\n });\n\n return this;\n }\n\n /**\n * This method stops media.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {MediaModule} Return value is for method chain.\n */\n public stop(successCallback?: () => void, errorCallback?: (error: Error) => void): MediaModule {\n if ((this.source === null) || (this.media === null)) {\n return this;\n }\n\n // ref: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted\n this.media.play()\n .then(() => {\n if (this.media === null) {\n return;\n }\n\n this.media.pause();\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n if (successCallback) {\n successCallback();\n }\n })\n .catch((error: Error) => {\n if (errorCallback) {\n errorCallback(error);\n }\n });\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for media module.\n * This method is overloaded for type interface and type check.\n * @param {keyof MediaModuleParams|MediaModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {MediaModuleParams[keyof MediaModuleParams]|MediaModule} Return value is parameter for media module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'autoplay'): boolean;\n public param(params: 'playbackRate'): number;\n public param(params: 'currentTime'): number;\n public param(params: 'controls'): boolean;\n public param(params: 'loop'): boolean;\n public param(params: 'muted'): boolean;\n public param(params: 'duration'): boolean;\n public param(params: 'duration'): boolean;\n public param(params: MediaModuleParams): MediaModule;\n public param(params: keyof MediaModuleParams | MediaModuleParams): MediaModuleParams[keyof MediaModuleParams] | MediaModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'autoplay': {\n return this.autoplay;\n }\n\n case 'playbackRate': {\n return this.media?.playbackRate ?? 1;\n }\n\n case 'currentTime': {\n return this.media?.currentTime ?? 0;\n }\n\n case 'controls': {\n return this.media?.controls ?? false;\n }\n\n case 'loop': {\n return this.media?.loop ?? false;\n }\n\n case 'muted': {\n return this.media?.muted ?? false;\n }\n\n case 'duration': {\n // `duration` is infinite in case of audio streaming\n return Number.isNaN(this.media?.duration) ? 0 : (this.media?.duration ?? 0); // Getter only\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'playbackRate': {\n if (this.media && (typeof value === 'number')) {\n if (value > 0) {\n this.media.playbackRate = value;\n\n const startTime = this.context.currentTime;\n const currentTime = this.media.currentTime;\n const duration = this.media.duration;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - currentTime) / value)), true);\n }\n }\n }\n\n break;\n }\n\n case 'currentTime': {\n if (this.media && (typeof value === 'number')) {\n this.media.currentTime = value;\n\n const startTime = this.context.currentTime;\n const duration = this.media.duration;\n const playbackRate = this.media.playbackRate;\n\n this.envelopegenerator.start(startTime);\n\n // `duration` is infinite in case of audio streaming\n if (Number.isFinite(duration)) {\n this.envelopegenerator.stop((startTime + ((duration - value) / playbackRate)), true);\n }\n }\n\n break;\n }\n\n case 'controls': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.controls = value;\n }\n\n break;\n }\n\n case 'loop': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.loop = value;\n }\n\n break;\n }\n\n case 'muted': {\n if (this.media && (typeof value === 'boolean')) {\n this.media.muted = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `MediaElementAudioSourceNode`.\n * @return {MediaElementAudioSourceNode|null}\n */\n public get(): MediaElementAudioSourceNode | null {\n return this.source;\n }\n\n /**\n * This method determines whether instance of `HTMLMediaElement` exists.\n * @return {boolean} If instance of `HTMLMediaElement` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public hasMedia(): boolean {\n return this.media !== null;\n }\n\n /**\n * This method determines whether instance of `MediaElementAudioSourceNode` exists.\n * @return {boolean} If instance of `MediaElementAudioSourceNode` already exists, this value is `true`. Otherwise, this value is `false`.\n */\n public hasSource(): boolean {\n return this.source !== null;\n }\n\n /**\n * This method determines whether media is paused.\n * @return {boolean} If media is paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return (this.media === null) ? true : this.media.paused;\n }\n\n /**\n * This method gets or sets 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|MediaModule} Return value is fade-in time. Otherwise, return value is for method chain.\n */\n public fadeIn(time?: number): number | MediaModule {\n if (typeof time !== 'number') {\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.media?.currentTime ?? 0;\n const duration = this.media?.duration ?? 0;\n const playbackRate = this.media?.playbackRate ?? 1;\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 gets or sets 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|MediaModule} Return value is fade-out time. Otherwise, return value is for method chain.\n */\n public fadeOut(time?: number): number | MediaModule {\n if (typeof time !== 'number') {\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.media?.currentTime ?? 0;\n const duration = this.media?.duration ?? 0;\n const playbackRate = this.media?.playbackRate ?? 1;\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 requests Picture In Picture (PIP).\n * @return {Promise<PictureInPictureWindow>} Return value is `Promise`.\n */\n public requestPictureInPicture(): Promise<PictureInPictureWindow> {\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<void>} Return value is `Promise`.\n */\n public exitPictureInPicture(): Promise<void> {\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 /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets media module parameters as associative array.\n * @return {MediaModuleParams}\n * @override\n */\n public override params(): Required<MediaModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n autoplay : this.autoplay,\n playbackRate : this.media?.playbackRate ?? 1,\n controls : this.media?.controls ?? false,\n loop : this.media?.loop ?? false,\n muted : this.media?.muted ?? false,\n currentTime : this.media?.currentTime ?? 0,\n duration : Number.isNaN(this.media?.duration ?? 0) ? 0 : (this.media?.duration ?? 0),\n vocalcanceler: this.vocalcanceler.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceOpen(event: Event): void {\n if (this.mediaSource === null) {\n return;\n }\n\n this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeType);\n\n this.sourceBuffer.mode = 'sequence';\n\n this.sourceBuffer.addEventListener('updateend', this.onSourceBufferUpdateEnd, false);\n this.sourceBuffer.addEventListener('error', this.onSourceBufferError, false);\n\n const request = new Request(this.file);\n\n fetch(request)\n .then((response: Response) => {\n return response.arrayBuffer();\n })\n .then((data: ArrayBuffer) => {\n if (this.sourceBuffer) {\n this.sourceBuffer.appendBuffer(data);\n }\n })\n .catch((error: Error) => {\n if (this.listeners.error) {\n this.listeners.error(error);\n }\n })\n .finally(() => {\n if (this.listeners.sourceopen) {\n this.listeners.sourceopen(event);\n }\n });\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceEnded(event: Event): void {\n if (this.listeners.sourceended) {\n this.listeners.sourceended(event);\n }\n }\n\n /**\n * This method is event listener for `MediaSource`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceClose(event: Event): void {\n if (this.listeners.sourceclose) {\n this.listeners.sourceclose(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceBufferUpdateEnd(event: Event): void {\n if (this.listeners.updateend) {\n this.listeners.updateend(event);\n }\n }\n\n /**\n * This method is event listener for `SourceBuffer`\n * @param {Event} event This argument is instance of `Event`.\n */\n private onSourceBufferError(event: Event): void {\n if (this.listeners.error) {\n this.listeners.error(event);\n }\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for sound source (bypass).\n */\nexport class StreamModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { StreamModuleProcessor } from './StreamModuleProcessor';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface MediaStreamTrackAudioSourceNode extends AudioNode {\n}\n\nexport type StreamModuleParams = SoundModuleParams & {\n output?: boolean,\n track?: boolean\n};\n\nexport { StreamModuleProcessor };\n\n/**\n * This class is for processing sound data from WebRTC.\n */\nexport class StreamModule extends SoundModule {\n private sources: MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[] = [];\n private stream: MediaStream | null = null;\n private constraints: MediaStreamConstraints = {\n audio: true,\n video: false\n };\n\n // Parameters\n private output = true;\n private track = false;\n\n private paused = true;\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, StreamModuleProcessor.name);\n }\n\n /**\n * This method sets up for using WebRTC.\n * @param {MediaStreamConstraints} constraints This argument is object based on `MediaStreamConstraints` dictionary.\n * @return {StreamModule} Return value is for method chain.\n */\n public setup(constraints?: MediaStreamConstraints): StreamModule {\n if (constraints) {\n this.constraints = { ...this.constraints, ...constraints };\n }\n\n return this;\n }\n\n /**\n * This method opens devices or sets instance of `MediaStream`.\n * @property {MediaStream} stream This argument is instance of `MediaStream`.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @return {Promise<MediaStream|Error>} Return value is `Promise` that `getUserMedia` returns.\n */\n public ready(params?: {\n stream?: MediaStream;\n successCallback?: (stream: MediaStream) => void;\n errorCallback?: (error: Error) => void;\n }): Promise<MediaStream|Error> {\n if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia || !window.MediaStream) {\n return Promise.reject();\n }\n\n this.paused = false;\n\n if (params?.stream) {\n this.stream = params.stream;\n return Promise.resolve(this.stream);\n }\n\n return navigator.mediaDevices.getUserMedia(this.constraints)\n .then((stream: MediaStream) => {\n if (this.paused) {\n return stream;\n }\n\n this.stream = stream;\n\n if (params?.successCallback) {\n params.successCallback(stream);\n }\n\n return stream;\n })\n .catch((error: Error) => {\n if (params?.errorCallback) {\n params.errorCallback(error);\n }\n\n return error;\n });\n }\n\n /**\n * This method starts streaming.\n * @return {StreamModule} Return value is for method chain.\n */\n public start(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n if (this.track) {\n // Get instance of `MediaStreamTrack` for audio\n const audioTracks = this.stream.getAudioTracks();\n\n for (let i = 0, len = audioTracks.length; i < len; i++) {\n // @ts-expect-error `createMediaStreamTrackSource` is not defined\n this.sources[i] = this.context.createMediaStreamTrackSource(audioTracks[i]);\n\n // MediaStreamTrackAudioSourceNode (Input) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.sources[i].connect(this.processor);\n this.connect(this.processor);\n }\n } else {\n this.sources[0] = this.context.createMediaStreamSource(this.stream);\n\n // MediaStreamAudioSourceNode (Input) -> AudioWorkletNode -> ... -> AudioDestinationNode (Output)\n this.sources[0].connect(this.processor);\n this.connect(this.processor);\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 recorder\n this.mastervolume.connect(this.recorder.INPUT);\n this.recorder.OUTPUT.connect(this.destination);\n }\n\n this.on(this.context.currentTime);\n\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n return this;\n }\n\n /**\n * This method stops streaming.\n * @return {StreamModule} Return value is for method chain.\n */\n public stop(): StreamModule {\n this.sources.length = 0;\n\n this.off(this.context.currentTime);\n\n this.analyser.stop('time', 0);\n this.analyser.stop('time', 1);\n this.analyser.stop('fft', 0);\n this.analyser.stop('fft', 1);\n this.analyser.stop('spectrogram', 0);\n this.analyser.stop('spectrogram', 1);\n\n this.paused = true;\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for stream module.\n * This method is overloaded for type interface and type check.\n * @param {keyof StreamModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {StreamModuleParams[keyof StreamModuleParams]|StreamModule} Return value is parameter for stream module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: 'output'): boolean;\n public param(params: 'track'): boolean;\n public param(params: StreamModuleParams): StreamModule;\n public param(params: keyof StreamModuleParams | StreamModuleParams): StreamModuleParams[keyof StreamModuleParams] | StreamModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n\n case 'output': {\n return this.output;\n }\n\n case 'track': {\n return this.track;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n\n case 'output': {\n if (typeof value === 'boolean') {\n this.output = value;\n }\n\n break;\n }\n\n case 'track': {\n if (typeof value === 'boolean') {\n this.track = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode` or that array contains these.\n * This method is overloaded for type interface and type check.\n * @param {number} index This argument selects instance of `MediaStreamAudioSourceNode` or `MediaStreamTrackAudioSourceNode`.\n * @return {MediaStreamAudioSourceNode|MediaStreamTrackAudioSourceNode}\n */\n public get(index: number): MediaStreamAudioSourceNode | MediaStreamTrackAudioSourceNode;\n public get(): MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[];\n public get(index?: number): MediaStreamAudioSourceNode | MediaStreamTrackAudioSourceNode | MediaStreamAudioSourceNode[] | MediaStreamTrackAudioSourceNode[] {\n if ((typeof index === 'number') && (index >= 0) && (index < this.sources.length)) {\n return this.sources[index];\n }\n\n return this.sources;\n }\n\n /**\n * This method gets instance of `MediaStream`.\n * @return {MediaStream|null}\n */\n public getStream(): MediaStream | null {\n return this.stream;\n }\n\n /**\n * This method gets current `MediaStreamConstraints`.\n * @return {MediaStreamConstraints}\n */\n public getConstraints(): MediaStreamConstraints {\n return this.constraints;\n }\n\n /**\n * This method changes `MediaStreamConstraints`.\n * @param {MediaStreamConstraints} constraints This argument is object based on `MediaStreamConstraints` dictionary.\n * @return {StreamModule} Return value is for method chain.\n */\n public setConstraints(constraints: MediaStreamConstraints): StreamModule {\n this.constraints = constraints;\n return this;\n }\n\n /**\n * This method stops microphone and camera by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clear(): StreamModule {\n this.stop();\n\n this.clearAudioDevices();\n this.clearVideoDevices();\n\n this.stream = null;\n\n return this;\n }\n\n /**\n * This method stops microphone by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clearAudioDevices(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get 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 camera by stopping instances of `MediaStreamTrack`.\n * @return {StreamModule} Return value is for method chain.\n */\n public clearVideoDevices(): StreamModule {\n if (this.stream === null) {\n return this;\n }\n\n this.stop();\n\n // Get 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 instance of `MediaDeviceInfo`.\n * @return {Promise<MediaDeviceInfo[]|void>} Return value is `Promise` that has array contains instance of `MediaDeviceInfo`.\n */\n public devices(): Promise<MediaDeviceInfo[]|void> {\n if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {\n return Promise.reject();\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 public streaming(): boolean {\n return !this.paused;\n }\n\n /**\n * This method enables to designate input device.\n * @param {string} deviceId This argument is string as input device ID.\n * @return {StreamModule} Return value is for method chain.\n */\n public setInputDeviceId(deviceId: string): StreamModule {\n const audioConstraints = this.constraints.audio ?? {};\n\n if (typeof audioConstraints === 'boolean') {\n this.constraints = {\n ...this.constraints,\n audio: {\n deviceId\n }\n };\n } else {\n this.constraints = {\n ...this.constraints,\n audio: {\n ...audioConstraints,\n deviceId\n }\n };\n }\n\n return this;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /**\n * This method gets stream module parameters as associative array.\n * @return {StreamModuleParams}\n * @override\n */\n public override params(): Required<StreamModuleParams> {\n const params = super.params();\n\n return {\n ...params,\n output : this.output,\n track : this.track,\n noisegate : this.noisegate.params(),\n noisesuppressor: this.noisesuppressor.params()\n };\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\n\n/**\n * This subclass is for using `AudioWorkletNode` as sound source.\n */\nexport class ProcessorModule extends SoundModule {\n private processorName = '';\n private options: AudioWorkletNodeOptions = {};\n private moduleURL = '';\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.envelopegenerator.setGenerator(0);\n }\n\n /**\n * This method sets registered processor name and options for `AudioWorkletNode` constructor.\n * @param {string} processorName This argument is name of `AudioWorkletProcessor`.\n * @param {AudioWorkletNodeOptions} options This argument is object based on `AudioWorkletNodeOptions` dictionary.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public setup(processorName: string, options?: AudioWorkletNodeOptions): ProcessorModule {\n this.processorName = processorName;\n this.options = options ?? {};\n\n return this;\n }\n\n /**\n * This method adds module for AudioWorklet and creates instance of `AudioWorkletNode`.\n * @param {string} moduleURL This argument is string that contains URL of file (.js) with module to add.\n * @param {WorkletOptions} options This argument is one of 'omit', 'same-origin', 'include'. The default value is 'same-origin'.\n * @return {Promise<void>} Return value is `Promise` that `addModule` returns.\n */\n public ready(moduleURL: string, options?: WorkletOptions): Promise<void> {\n this.moduleURL = moduleURL;\n\n return this.context.audioWorklet.addModule(this.moduleURL, options ?? { credentials: 'same-origin' })\n .then(() => {\n this.processor = new AudioWorkletNode(this.context, this.processorName, this.options);\n });\n }\n\n /**\n * This method starts sound by connecting to `AudioDestinationNode`.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public start(): ProcessorModule {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator === null) {\n return this;\n }\n\n const startTime = this.context.currentTime;\n\n if (!this.mixed) {\n // Clear previous\n this.envelopegenerator.clear(true);\n this.processor.disconnect(0);\n\n // GainNode (Envelope Generator) -> ... -> AudioDestinationNode (Output)\n this.connect(generator);\n }\n\n // AudioWorkletNode (Input) -> GainNode (Envelope Generator)\n this.envelopegenerator.ready(0, this.processor, null);\n\n this.envelopegenerator.start(startTime);\n\n if (!this.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n this.on(startTime);\n\n return this;\n }\n\n /**\n * This method stops sound by disconnecting to `AudioDestinationNode`.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public stop(): ProcessorModule {\n const stopTime = this.context.currentTime;\n\n this.envelopegenerator.stop(stopTime);\n this.off(stopTime);\n\n return this;\n }\n\n /**\n * This method sends message from `MessagePort` that `AudioWorkletNode` has.\n * @param {unknown} data This argument is sent as any data.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public postMessage(data: unknown): ProcessorModule {\n this.processor.port.postMessage(data);\n\n return this;\n }\n\n /**\n * This method sets event handler that is invoked on receiving message.\n * @param {function} callback This argument is invoked on receiving message.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public onMessage(callback: (event: MessageEvent) => void): ProcessorModule {\n this.processor.port.onmessage = callback;\n\n return this;\n }\n\n /**\n * This method sets event handler that is invoked on receiving message that cannot be deserialized.\n * @param {function} callback This argument is invoked on receiving message that cannot be deserialized.\n * @return {ProcessorModule} Return value is for method chain.\n */\n public onMessageError(callback: (event: MessageEvent) => void): ProcessorModule {\n this.processor.port.onmessageerror = callback;\n\n return this;\n }\n\n /**\n * This method gets map based on `AudioParamMap`.\n * @return {AudioParamMap|null}\n */\n public map(): AudioParamMap {\n return this.processor.parameters;\n }\n\n /**\n * This method gets instance of `AudioWorkletNode`.\n * @return {AudioWorkletNode|null}\n */\n public get(): AudioWorkletNode {\n return this.processor;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override suspend() {\n super.suspend();\n\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (this.processor && generator) {\n generator.disconnect(0);\n this.processor.connect(generator);\n }\n\n return this;\n }\n\n /** @override */\n public override get INPUT(): GainNode | null {\n const generator = this.envelopegenerator.getGenerator(0);\n\n if (generator) {\n return generator;\n }\n\n return null;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","import type { Inputs, Outputs } from '../worklet';\n\nimport { AudioWorkletProcessor } from '../worklet';\n\n/**\n * This class extends `AudioWorkletProcessor`.\n * Overrides `process` method for mixing sound source.\n */\nexport class MixerModuleProcessor extends AudioWorkletProcessor {\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n super();\n }\n\n /** @override */\n protected override process(inputs: Inputs, outputs: Outputs): boolean {\n const input = inputs[0];\n const output = outputs[0];\n\n for (let channelNumber = 0, numberOfChannels = input.length; channelNumber < numberOfChannels; channelNumber++) {\n output[channelNumber].set(input[channelNumber]);\n }\n\n return true;\n }\n}\n","import type { SoundModuleParams, Module, ModuleName } from '../SoundModule';\nimport type { Analyser } from '../SoundModule/Analyser';\nimport type { Recorder } from '../SoundModule/Recorder';\nimport type { Autopanner } from '../SoundModule/Effectors/Autopanner';\nimport type { BitCrusher } from '../SoundModule/Effectors/BitCrusher';\nimport type { Chorus } from '../SoundModule/Effectors/Chorus';\nimport type { Compressor } from '../SoundModule/Effectors/Compressor';\nimport type { Delay } from '../SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator } from '../SoundModule/Effectors/EnvelopeGenerator';\nimport type { Equalizer } from '../SoundModule/Effectors/Equalizer';\nimport type { Filter } from '../SoundModule/Effectors/Filter';\nimport type { Flanger } from '../SoundModule/Effectors/Flanger';\nimport type { Fuzz } from '../SoundModule/Effectors/Fuzz';\nimport type { Listener } from '../SoundModule/Effectors/Listener';\nimport type { NoiseGate } from '../SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressor } from '../SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDrive } from '../SoundModule/Effectors/OverDrive';\nimport type { Panner } from '../SoundModule/Effectors/Panner';\nimport type { Phaser } from '../SoundModule/Effectors/Phaser';\nimport type { PitchShifter } from '../SoundModule/Effectors/PitchShifter';\nimport type { Preamp } from '../SoundModule/Effectors/Preamp';\nimport type { Reverb } from '../SoundModule/Effectors/Reverb';\nimport type { Ringmodulator } from '../SoundModule/Effectors/Ringmodulator';\nimport type { Stereo } from '../SoundModule/Effectors/Stereo';\nimport type { Tremolo } from '../SoundModule/Effectors/Tremolo';\nimport type { VocalCanceler } from '../SoundModule/Effectors/VocalCanceler';\nimport type { Wah } from '../SoundModule/Effectors/Wah';\n\nimport { SoundModule } from '../SoundModule';\nimport { MixerModuleProcessor } from './MixerModuleProcessor';\n\nexport { MixerModuleProcessor };\n\n/**\n * This class is for mixing sound sources (instance of `SoundModule` subclass).\n */\nexport class MixerModule extends SoundModule {\n private sources: SoundModule[] = [];\n private gainNodes: GainNode[] = [];\n\n /**\n * @param {AudioContext} context This argument is in order to use Web Audio API.\n */\n constructor(context: AudioContext) {\n super(context);\n\n this.processor = new AudioWorkletNode(context, MixerModuleProcessor.name);\n }\n\n /**\n * This method defines noop for the same API.\n */\n public setup(): MixerModule {\n // Noop\n return this;\n }\n\n /**\n * This method defines noop for the same API.\n */\n public ready(): MixerModule {\n // Noop\n return this;\n }\n\n /**\n * This method mixes sound sources (instance of `SoundModule` subclass).\n * @param {Array<SoundModule>} sources This argument is array that contains sound sources.\n * @param {Array<number>} gains This argument is array for each sound source volume.\n * @return {MixerModule} Return value is for method chain.\n */\n public start(sources: SoundModule[], gains?: number[]): MixerModule {\n this.sources = sources;\n\n for (let i = 0, len = this.sources.length; i < len; i++) {\n const source = this.sources[i];\n\n const stopTime = this.context.currentTime;\n\n source.off(stopTime);\n source.suspend();\n source.mix();\n\n if (source.INPUT) {\n this.gainNodes[i] = this.context.createGain();\n\n this.gainNodes[i].gain.value = gains ? gains[i] : 1;\n\n // Disconnect each connection to `AudioDestinationNode`\n source.disconnect();\n\n // AudioWorkletNode (each sound source) -> GainNode (each sound source volume) -> AudioWorkletNode (Mix sound sources)\n source.INPUT.connect(this.gainNodes[i]);\n this.gainNodes[i].connect(this.processor);\n }\n }\n\n // (... ->) AudioWorkletNode (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.runningAnalyser) {\n this.analyser.start('time', 0);\n this.analyser.start('time', 1);\n this.analyser.start('fft', 0);\n this.analyser.start('fft', 1);\n this.analyser.start('spectrogram', 0);\n this.analyser.start('spectrogram', 1);\n\n this.runningAnalyser = true;\n }\n\n return this;\n }\n\n /**\n * This method demixes sound sources (instance of `SoundModule` subclass).\n * @return {MixerModule} Return value is for method chain.\n */\n public stop(): MixerModule {\n const stopTime = this.context.currentTime;\n\n this.off(stopTime);\n this.suspend();\n\n // Revert connection\n for (const source of this.sources) {\n source.demix();\n\n if (source.INPUT) {\n source.disconnect();\n source.connect(source.INPUT);\n }\n }\n\n for (const gainNode of this.gainNodes) {\n gainNode.disconnect(0);\n }\n\n return this;\n }\n\n /**\n * This method gets or sets parameters for mixer module.\n * This method is overloaded for type interface and type check.\n * @param {keyof SoundModuleParams|SoundModuleParams} params This argument is string if getter. Otherwise, setter.\n * @return {SoundModuleParams[keyof SoundModuleParams]|MixerModule} Return value is parameter for mixer module if getter.\n * Otherwise, return value is for method chain.\n */\n public param(params: 'mastervolume'): number;\n public param(params: SoundModuleParams): MixerModule;\n public param(params: keyof SoundModuleParams | SoundModuleParams): SoundModuleParams[keyof SoundModuleParams] | MixerModule {\n if (typeof params === 'string') {\n switch (params) {\n case 'mastervolume': {\n return this.mastervolume.gain.value;\n }\n }\n }\n\n for (const [key, value] of Object.entries(params)) {\n switch (key) {\n case 'mastervolume': {\n if (typeof value === 'number') {\n this.mastervolume.gain.value = value;\n }\n\n break;\n }\n }\n }\n\n return this;\n }\n\n /**\n * This method gets array that contains instance of `SoundModule` subclass.\n * @return {Array<SoundModule>}\n */\n public get(): SoundModule[] {\n return this.sources;\n }\n\n /**\n * This method gets instance of `Module` (Analyser, Recorder, Effector ... etc).\n * @param {ModuleName} moduleName This argument selects module.\n * @return {Module}\n */\n public module(moduleName: 'analyser'): Analyser;\n public module(moduleName: 'recorder'): Recorder;\n public module(moduleName: 'autopanner'): Autopanner;\n public module(moduleName: 'bitcrusher'): BitCrusher;\n public module(moduleName: 'chorus'): Chorus;\n public module(moduleName: 'compressor'): Compressor;\n public module(moduleName: 'delay'): Delay;\n public module(moduleName: 'envelopegenerator'): EnvelopeGenerator;\n public module(moduleName: 'equalizer'): Equalizer;\n public module(moduleName: 'filter'): Filter;\n public module(moduleName: 'flanger'): Flanger;\n public module(moduleName: 'fuzz'): Fuzz;\n public module(moduleName: 'listener'): Listener;\n public module(moduleName: 'noisegate'): NoiseGate;\n public module(moduleName: 'noisesuppressor'): NoiseSuppressor;\n public module(moduleName: 'overdrive'): OverDrive;\n public module(moduleName: 'panner'): Panner;\n public module(moduleName: 'phaser'): Phaser;\n public module(moduleName: 'pitchshifter'): PitchShifter;\n public module(moduleName: 'preamp'): Preamp;\n public module(moduleName: 'reverb'): Reverb;\n public module(moduleName: 'ringmodulator'): Ringmodulator;\n public module(moduleName: 'stereo'): Stereo;\n public module(moduleName: 'tremolo'): Tremolo;\n public module(moduleName: 'vocalcanceler'): VocalCanceler;\n public module(moduleName: 'wah'): Wah;\n public module(moduleName: ModuleName): Module {\n switch (moduleName) {\n case 'analyser': {\n return this.analyser;\n }\n\n case 'recorder': {\n return this.recorder;\n }\n\n case 'autopanner': {\n return this.autopanner;\n }\n\n case 'bitcrusher': {\n return this.bitcrusher;\n }\n\n case 'chorus': {\n return this.chorus;\n }\n\n case 'compressor': {\n return this.compressor;\n }\n\n case 'delay': {\n return this.delay;\n }\n\n case 'envelopegenerator': {\n return this.envelopegenerator;\n }\n\n case 'equalizer': {\n return this.equalizer;\n }\n\n case 'filter': {\n return this.filter;\n }\n\n case 'flanger': {\n return this.flanger;\n }\n\n case 'fuzz': {\n return this.fuzz;\n }\n\n case 'listener': {\n return this.listener;\n }\n\n case 'noisegate': {\n return this.noisegate;\n }\n\n case 'noisesuppressor': {\n return this.noisesuppressor;\n }\n\n case 'overdrive': {\n return this.overdrive;\n }\n\n case 'panner': {\n return this.panner;\n }\n\n case 'phaser': {\n return this.phaser;\n }\n\n case 'pitchshifter': {\n return this.pitchshifter;\n }\n\n case 'preamp': {\n return this.preamp;\n }\n\n case 'reverb': {\n return this.reverb;\n }\n\n case 'ringmodulator': {\n return this.ringmodulator;\n }\n\n case 'stereo': {\n return this.stereo;\n }\n\n case 'tremolo': {\n return this.tremolo;\n }\n\n case 'vocalcanceler': {\n return this.vocalcanceler;\n }\n\n case 'wah': {\n return this.wah;\n }\n }\n }\n\n /** @override */\n public override get INPUT(): AudioWorkletNode {\n return this.processor;\n }\n\n /** @override */\n public override get OUTPUT(): GainNode {\n return this.mastervolume;\n }\n}\n","/**\n * This class is for using Web MIDI API.\n */\nexport class MIDI {\n private midiAccess: MIDIAccess | null = null;\n private inputs: MIDIInput[] = [];\n private outputs: MIDIOutput[] = [];\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n }\n\n /**\n * This method invokes `requestMIDIAccess` and gets instance of `MIDIAccess`.\n * @property {MIDIOptions} options This argument is object based on `MIDIOptions` dictionary.\n * @property {function} successCallback This argument is invoked on `requestMIDIAccess` success.\n * @property {function} errorCallback This argument is invoked on `requestMIDIAccess` failure.\n * @return {Promise<MIDIAccess|void>} Return value is `Promise` that `requestMIDIAccess` method returns.\n */\n public setup(params: {\n options?: MIDIOptions;\n successCallback?(midiAccess: MIDIAccess, midiInputs: MIDIInput[], midiOutputs: MIDIOutput[]): void;\n errorCallback?(error: Error): void;\n }): Promise<MIDIAccess|void> {\n if (!navigator.requestMIDIAccess) {\n return Promise.reject();\n }\n\n const { options, successCallback, errorCallback } = params;\n\n return navigator.requestMIDIAccess(options)\n .then((midiAccess: MIDIAccess) => {\n this.midiAccess = midiAccess;\n\n midiAccess.inputs.forEach((input: MIDIInput) => {\n this.inputs.push(input);\n });\n\n midiAccess.outputs.forEach((output: MIDIOutput) => {\n this.outputs.push(output);\n });\n\n if (successCallback) {\n successCallback(this.midiAccess, this.inputs, this.outputs);\n }\n })\n .catch((error: Error) => {\n if (errorCallback) {\n errorCallback(error);\n }\n });\n }\n\n /**\n * This method gets instance of `MIDIAccess`.\n * @return {MIDIAccess|null}\n */\n public get(): MIDIAccess | null {\n return this.midiAccess;\n }\n}\n","/**\n * This function returns worker script as string by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {string} Return value is worker script as string.\n */\nexport function extractWorkerString(workerContainerString: string): string {\n return workerContainerString.replace(/^.+?\\{/s, '').replace(/\\};?$/s, '');\n}\n\n/**\n * This function returns worker script as `Blob` by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {Blob} Return value is worker script as `Blob`.\n */\nexport function createWorkerBlob(workerContainerString: string): Blob {\n return new Blob([extractWorkerString(workerContainerString)], { type: 'text/javascript' });\n}\n\n/**\n * This function returns worker script as Object URL by removing container string.\n * @param {string} workerContainerString This argument is string that contains worker script.\n * @return {string} Return value is worker script as Object URL.\n */\nexport function createWorkerObjectURL(workerContainerString: string): string {\n return window.URL.createObjectURL(createWorkerBlob(workerContainerString));\n}\n","export type TokenType = 'TEMPO' | 'OCTAVE' | 'NOTE' | 'REST' | 'NUMBER' | 'TIE' | 'SPACE' | 'EOS' | 'UNKNOWN';\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<string|undefined, TokenType>([\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 class is entity for MML token.\n * This class has token type, token data and token value if token is number.\n */\nexport class Token {\n private _id: string;\n private _type: TokenType;\n private _token: string | undefined;\n private _value: number;\n\n /**\n * @param {string} id This argument is string that identifies MML token.\n * @param {TokenType} type This argument is one of 'TEMPO', 'OCTAVE', 'NOTE', 'REST', 'NUMBER', 'TIE', 'SPACE', 'EOS', 'UNKNOWN'.\n * @param {string|undefined} token This argument is string that constructs of token.\n */\n constructor(id: string, type: TokenType, token: string | undefined) {\n this._id = id;\n this._type = type;\n this._token = token;\n this._value = token ? Number(token) : -1;\n }\n\n /**\n * This method is getter for token type.\n */\n public get type(): TokenType {\n return this._type;\n }\n\n /**\n * This method is getter for token.\n */\n public get token(): string | undefined {\n return this._token;\n }\n\n /**\n * This method is getter for token value if token is number.\n */\n public get value(): number {\n return Number.isNaN(this._value) ? -1 : this._value;\n }\n\n /**\n * This method returns fields that `Token` has as JSON.\n */\n public toString(): string {\n return JSON.stringify({\n id : this._id,\n type : this._type,\n token: this._token,\n value: this._value\n });\n }\n}\n","import { TokenMap, Token } from './Token';\n\n/**\n * This class is for MML Tokenization.\n */\nexport class Tokenizer {\n public static id = 0;\n\n private tokens: string[] = [];\n private notes: string[] = [];\n private numbers: string[] = [];\n\n /**\n * @param {string} mml This argument is MML string.\n */\n constructor(mml: string) {\n // `reverse` for getting token by `pop`\n this.tokens = mml.trim().toUpperCase().split('').reverse();\n }\n\n /**\n * This method executes tokenization from MML.\n * @return {Token|null} Return value is instance of `Token`.\n */\n public get(): Token | null {\n let token = this.tokens.pop();\n let tokenType = TokenMap.get(token);\n\n Tokenizer.id++;\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while ((tokenType === 'SPACE')) {\n token = this.tokens.pop();\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n if (tokenType === 'EOS') {\n return new Token(Tokenizer.id.toString(10), 'EOS', token);\n }\n\n this.notes.length = 0;\n this.numbers.length = 0;\n\n switch (tokenType) {\n case 'TEMPO': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'TEMPO', token);\n }\n\n break;\n }\n\n case 'OCTAVE': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'OCTAVE', token);\n }\n\n break;\n }\n\n case 'NOTE': {\n if (token) {\n this.notes.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while (tokenType === 'NOTE') {\n this.notes.push(token);\n\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(Tokenizer.id.toString(10), 'NOTE', this.notes.join(''));\n }\n\n break;\n }\n\n case 'REST': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'REST', token);\n }\n\n break;\n }\n\n case 'NUMBER': {\n if (token) {\n this.numbers.push(token);\n\n // Look-ahead\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n\n while (tokenType === 'NUMBER') {\n this.numbers.push(token);\n\n token = this.tokens.pop();\n\n if (!token) {\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n tokenType = TokenMap.get(token);\n\n if (!tokenType) {\n return new Token(Tokenizer.id.toString(10), 'UNKNOWN', token);\n }\n }\n\n // Look-behind\n this.tokens.push(token);\n\n return new Token(Tokenizer.id.toString(10), 'NUMBER', this.numbers.join(''));\n }\n\n break;\n }\n\n case 'TIE': {\n if (token) {\n return new Token(Tokenizer.id.toString(10), 'TIE', token);\n }\n\n break;\n }\n }\n\n return null;\n }\n}\n","import type { Token } from '../../src/MML/Token';\n\n/**\n * This class is entity for MML syntax tree.\n */\nexport class Tree {\n private static indent = 0;\n\n private _id: string;\n\n private _operator: Token;\n\n \n private _left: Tree | null;\n private _right: Tree | null;\n \n\n /**\n * @param {string} id This argument is string that identifies syntax tree node.\n * @param {Token} operator This argument is instance of `Token` as syntax tree node.\n * @param {Tree} left This argument is instance of `Tree` as left subtree.\n * @param {Tree} right This argument is instance of `Tree` as right subtree.\n */\n constructor(id: string, operator: Token, left: Tree | null, right: Tree | null) {\n this._id = id;\n this._operator = operator;\n this._left = left;\n this._right = right;\n }\n\n /**\n * This method concatenates subtree as right subtree.\n * @param {Tree} node This argument is instance of `Tree` as syntax tree node.\n */\n public concat(node: Tree): void {\n this._right = node; // Side Effect (Because of pointers that before and after trees have)\n }\n\n /**\n * This method is getter for operator.\n */\n public get operator(): Token {\n return this._operator;\n }\n\n /**\n * This method is getter for left subtree.\n */\n public get left(): Tree | null {\n return this._left;\n }\n\n /**\n * This method is getter for right subtree.\n */\n public get right(): Tree | null {\n return this._right;\n }\n\n /**\n * This method clears indent.\n */\n public clear(): void {\n Tree.indent = 0;\n }\n\n /**\n * This method represents tree status as string.\n */\n public toString(): string {\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.token} (id = ${this._id})`}\n${space} /\\\\\n${space}${this._left?.operator.token ?? ''}${((this._right !== null) && (this._right._operator.token !== undefined)) ? this.toString.call(this._right) : 'EOS'}\n`;\n }\n}\n\n/**\n * This class is error class for MML syntax error.\n */\nexport class MMLSyntaxError {\n private _token: Token;\n\n /**\n * @param {Token} token This argument is instance of `Token` that error occurs in.\n */\n constructor(token: Token) {\n this._token = token;\n }\n\n /**\n * This method is getter for instance of `Token`.\n */\n public get token(): Token {\n return this._token;\n }\n}\n","import { Tokenizer } from './Tokenizer';\nimport { Tree, MMLSyntaxError } from './Tree';\n\n/**\n * This class is Tree Construction (syntax tree) for MML (Music Macro Language).\n */\nexport class TreeConstructor {\n public static id = 0;\n\n private tokenizer: Tokenizer;\n private syntaxTree: Tree[] = [];\n\n /**\n * @param {Tokenizer} tokenizer This argument is instance of `Tokenizer`.\n */\n constructor(tokenizer: Tokenizer) {\n this.tokenizer = tokenizer;\n }\n\n /**\n * This method executes tree construction (parsing) from tokens.\n * @return {Array<Tree>|MMLSyntaxError} Return value is syntax tree.\n */\n public parse(): Tree[] | MMLSyntaxError {\n Tokenizer.id = 0;\n\n let token = this.tokenizer.get();\n let nextToken = this.tokenizer.get();\n\n while (true) {\n if (!token || !nextToken) {\n return this.syntaxTree;\n }\n\n TreeConstructor.id += 2;\n\n switch (token.type) {\n case 'TEMPO': {\n if (nextToken.type === 'NUMBER') {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), token, left, null);\n\n // /T\\d+/\n this.syntaxTree.push(tree);\n\n break;\n }\n\n return new MMLSyntaxError(token);\n }\n\n case 'OCTAVE': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'NOTE': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'REST': {\n if ((this.syntaxTree.length > 0) && (nextToken.type === 'NUMBER')) {\n const left = new Tree((TreeConstructor.id - 0).toString(10), nextToken, null, null); // Leaf\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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(token);\n }\n\n case 'NUMBER': {\n TreeConstructor.id -= 2;\n break;\n }\n\n case 'TIE': {\n if (this.syntaxTree.length > 0) {\n TreeConstructor.id--;\n\n const tree = new Tree((TreeConstructor.id - 0).toString(10), 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(token);\n }\n\n case 'EOS': {\n if (this.syntaxTree.length > 0) {\n const tree = new Tree((TreeConstructor.id - 1).toString(10), 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((TreeConstructor.id - 1).toString(10), token, null, null);\n\n this.syntaxTree.push(tree);\n }\n\n return this.syntaxTree;\n }\n }\n\n token = nextToken;\n nextToken = this.tokenizer.get();\n }\n }\n\n /**\n * This method releases memory that stack has.\n */\n public free(): void {\n this.syntaxTree.length = 0;\n }\n}\n","// @ts-expect-error Because of import WebAssembly Module\nimport wasm from './WebAssemblyModules/FFT.wasm';\n\n// Constants for Music\n\n// 12 equal temperament\n//\n// Min -> 27.5 Hz (A), Max -> 4186 Hz (C)\n//\n// A * 1.0594630943592953 -> A# (half up)\nexport const EQUAL_TEMPERAMENT = 12 as const;\nexport const FREQUENCY_RATIO = 1.0594630943592953 as const; // 2 ** (1 / EQUAL_TEMPERAMENT)\nexport const MIN_A = 27.5 as const;\nexport const QUARTER_NOTE = 4 as const;\nexport const SHARP = '#' as const;\nexport const HALF_UP = '+' as const;\nexport const HALF_DOWN = '-' as const;\nexport const DOT = '.' as const;\n\nexport type PitchChar = 'C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B' | 'R';\n\nexport type ConvertedTime = {\n minutes: number,\n seconds: number,\n milliseconds: number\n};\n\n/**\n * This predicate method determine whether is `PitchChar` type.\n * @param {string} pitchChar This argument is any string.\n * @return {boolean}\n */\nexport function isPitchChar(pitchChar: string): pitchChar is PitchChar {\n switch (pitchChar.toUpperCase()) {\n case 'C':\n case 'D':\n case 'E':\n case 'F':\n case 'G':\n case 'A':\n case 'B':\n case 'R': {\n return true;\n }\n\n default: {\n return false;\n }\n }\n}\n\n/**\n * This class (static) method computes index by octave and `PitchChar` string.\n * @param {number} octave This argument is octave.\n * @param {PitchChar} pitchChar This argument is `PitchChar` string.\n * @return {number} Return value is index that is computed by octave and pitch character.\n */\nexport function computeIndex(octave: number, pitchChar: PitchChar): number {\n let index = 0;\n\n switch (pitchChar) {\n case 'C': {\n index = 3;\n break;\n }\n\n case 'D': {\n index = 5;\n break;\n }\n\n case 'E': {\n index = 7;\n break;\n }\n\n case 'F': {\n index = 8;\n break;\n }\n\n case 'G': {\n index = 10;\n break;\n }\n\n case 'A': {\n index = 12;\n break;\n }\n\n case 'B': {\n index = 14;\n break;\n }\n\n case 'R': {\n return -1;\n }\n }\n\n const computedIndex = (EQUAL_TEMPERAMENT * (octave - 1)) + index;\n\n return (computedIndex >= 0) ? computedIndex : -1;\n}\n\n/**\n * This class (static) method computes frequency from index that corresponds to 12 equal temperament.\n * @param {number} index This argument is index that corresponds to 12 equal temperament.\n * For example, this value is between 0 and 88 in case of piano.\n * @return {number} Return value is frequency.\n */\nexport function computeFrequency(index: number): number {\n return (index >= 0) ? (MIN_A * (FREQUENCY_RATIO ** index)) : 0;\n}\n\n/**\n * This class (static) method computes frequency from `frequency` property and `detune` property (@see https://www.w3.org/TR/webaudio/#computedoscfrequency or https://www.w3.org/TR/webaudio/#computedfrequency).\n * @param {number} frequency This argument is `frequency` property as instance of `AudioParam`.\n * @param {number} detune This argument is `detune` property as instance of `AudioParam`.\n * @return {number} Return value is computed frequency (Hz).\n */\nexport function computeHz(frequency: number, detune: number): number {\n if (frequency <= 0) {\n return 0;\n }\n\n return frequency * (2 ** (detune/ 1200));\n}\n\n/**\n * This class (static) method computes playback rate from `playbackRate` property and `detune` property (@see https://www.w3.org/TR/webaudio/#computedplaybackrate).\n * @param {number} playbackRate This argument is `playbackRate` property as instance of `AudioParam`.\n * @param {number} detune This argument is `detune` property as instance of `AudioParam`.\n * @return {number} Return value is computed playback rate.\n */\nexport function computePlaybackRate(playbackRate: number, detune: number): number {\n if (playbackRate <= 0) {\n return 1;\n }\n\n return playbackRate * (2 ** (detune / 1200));\n}\n\nexport interface FileEvent extends Event {\n target: HTMLInputElement & EventTarget;\n}\n\n// Utility types and functions\n\nexport type FileReaderType = 'arraybuffer' | 'dataURL' | 'text' | 'json';\nexport type FileReaderErrorText = 'NOT_FOUND_ERR' | 'SECURITY_ERR' | 'ABORT_ERR' | 'NOT_READABLE_ERR' | 'ERR' | '';\n\nexport type WindowFunction = 'rect' | 'hanning' | 'hamming' | 'blackman';\n\n/**\n * This class (static) method applies window function\n * @param {number} size This argument is size of window function.\n * @param {WindowFunction} type This argument is type of window function. The default value is 'rect' (rectangular window).\n * @return {Float32Array} Return value is instance of `Float32Array` as window function.\n */\nexport function windowFunction(size: number, type: WindowFunction = 'rect'): Float32Array {\n if (size <= 0) {\n return new Float32Array([]);\n }\n\n const w = new Float32Array(size);\n\n switch (type) {\n case 'rect': {\n for (let n = 0; n < size; n++) {\n w[n] = 1.0;\n }\n\n break;\n }\n\n case 'hanning': {\n for (let n = 0; n < size; n++) {\n w[n] = 0.5 - (0.5 * Math.cos((2.0 * Math.PI * n) / (size - 1)));\n }\n\n break;\n }\n\n case 'hamming': {\n for (let n = 0; n < size; n++) {\n w[n] = 0.54 - (0.46 * Math.cos((2.0 * Math.PI * n) / (size - 1)));\n }\n\n break;\n }\n\n case 'blackman': {\n const alpha = 0.16;\n\n const a0 = (1.0 - alpha) / 2.0;\n const a1 = 1 / 2;\n const a2 = alpha / 2.0;\n\n for (let n = 0; n < size; n++) {\n w[n] = a0 - (a1 * Math.cos((2.0 * Math.PI * n) / (size - 1))) + (a2 * Math.cos((4.0 * Math.PI * n) / (size - 1)));;\n }\n\n break;\n }\n }\n\n return w;\n}\n\nexport interface FFTWebAssemblyInstance extends WebAssembly.Exports {\n memory: WebAssembly.Memory;\n FFT: (size: number) => void;\n IFFT: (size: number) => void;\n alloc_memory_reals: (size: number) => number;\n alloc_memory_imags: (size: number) => number;\n};\n\nlet instance: WebAssembly.Instance | null = null;\n\nWebAssembly.instantiateStreaming(fetch(wasm))\n .then((source: WebAssembly.WebAssemblyInstantiatedSource) => {\n instance = source.instance;\n })\n .catch((error: Error) => {\n return error;\n });\n\n/**\n * This class (static) method executes FFT.\n * @param {Float32Array} reals This argument is instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is FFT size (power of two).\n */\nexport function fft(reals: Float32Array, imags: Float32Array, size: number): void {\n if (instance === null) {\n return;\n }\n\n // HACK:\n const wasm = instance.exports as FFTWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetReal = wasm.alloc_memory_reals(size);\n const offsetImag = wasm.alloc_memory_imags(size);\n\n const realsLinearMemory = new Float32Array(linearMemory, offsetReal, size);\n const imagsLinearMemory = new Float32Array(linearMemory, offsetImag, size);\n\n realsLinearMemory.set(reals);\n imagsLinearMemory.set(imags);\n\n wasm.FFT(size);\n\n reals.set(realsLinearMemory);\n imags.set(imagsLinearMemory);\n}\n\n/**\n * This class (static) method executes IFFT.\n * @param {Float32Array} reals This argument is instance of `Float32Array` for real number.\n * @param {Float32Array} imags This argument is instance of `Float32Array` for imaginary number.\n * @param {number} size This argument is IFFT size (power of two).\n */\nexport function ifft(reals: Float32Array, imags: Float32Array, size: number): void {\n if (instance === null) {\n return;\n }\n\n // HACK:\n const wasm = instance.exports as FFTWebAssemblyInstance;\n\n const linearMemory = wasm.memory.buffer;\n\n const offsetReal = wasm.alloc_memory_reals(size);\n const offsetImag = wasm.alloc_memory_imags(size);\n\n const realsLinearMemory = new Float32Array(linearMemory, offsetReal, size);\n const imagsLinearMemory = new Float32Array(linearMemory, offsetImag, size);\n\n realsLinearMemory.set(reals);\n imagsLinearMemory.set(imags);\n\n wasm.IFFT(size);\n\n reals.set(realsLinearMemory);\n imags.set(imagsLinearMemory);\n}\n\n/**\n * This class (static) method retrieves resource on web by Ajax.\n * @property {string} url This argument is URL for resource.\n * @property {XMLHttpRequestResponseType} type This argument is response type that is one of 'arraybuffer', 'blob', 'document', 'json', 'text'. The default value is 'arraybuffer'.\n * @property {number} timeout This argument is timeout of Ajax. The default value is 60000 msec (1 minutes).\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked during receiving data.\n */\nexport function ajax(params: {\n url: string;\n type?: XMLHttpRequestResponseType;\n timeout?: number;\n successCallback?(event: ProgressEvent, respsonse: ArrayBuffer | Blob | Document | string): void;\n errorCallback?(event: ProgressEvent, textStatus: 'error' | 'timeout'): void;\n progressCallback?(event: ProgressEvent): void;\n}): void {\n const { url, type, timeout, successCallback, errorCallback, progressCallback } = params;\n\n // for error\n const ERROR_AJAX = 'error';\n const ERROR_AJAX_TIMEOUT = 'timeout';\n\n const xhr = new XMLHttpRequest();\n\n xhr.timeout = timeout ?? 60000;\n\n xhr.ontimeout = (event: ProgressEvent) => {\n if (errorCallback) {\n errorCallback(event, ERROR_AJAX_TIMEOUT);\n }\n };\n\n xhr.onprogress = (event: ProgressEvent) => {\n if (progressCallback) {\n progressCallback(event);\n }\n };\n\n xhr.onerror = (event: ProgressEvent) => {\n if (errorCallback) {\n errorCallback(event, ERROR_AJAX);\n }\n };\n\n xhr.onload = (event: ProgressEvent) => {\n if (successCallback && (xhr.status === 200)) {\n successCallback(event, xhr.response);\n }\n };\n\n xhr.open('GET', url, true);\n xhr.responseType = type ?? 'arraybuffer';\n xhr.send(null);\n}\n\n/**\n * This class (static) method calculates minutes, seconds and milliseconds from designated time (seconds).\n * @param {number} time This argument is time (seconds).\n * @return {ConvertedTime} Return value is converted time as associative array\n */\nexport function convertTime(time: number): ConvertedTime {\n if (time < 0) {\n return {\n minutes : -1,\n seconds : -1,\n milliseconds: -1\n };\n }\n\n const m = Math.trunc(time / 60);\n const s = Math.trunc(time % 60);\n const ms = time - Math.trunc(time);\n\n return {\n minutes : m,\n seconds : s,\n milliseconds: ms\n };\n}\n\n/**\n * This class (static) method decodes instance of `ArrayBuffer` to instance of `AudioBuffer`.\n * @param {AudioContext} context This argument is instance of `AudioContext` for `decodeAudioData` method.\n * @param {ArrayBuffer} arraybuffer This argument is decoded to instance of `AudioBuffer`.\n * @param {function} successCallback This argument is invoked on success.\n * @param {function} errorCallback This argument is invoked on failure.\n * @return {Promise<AudioBuffer>} Return value is instance of `Promise` that has instance of `AudioBuffer`.\n */\nexport function decode(\n context: AudioContext,\n arraybuffer: ArrayBuffer,\n successCallback?: (buffer: AudioBuffer) => void,\n errorCallback?: (error: Error) => void\n): Promise<AudioBuffer> {\n if (!successCallback) {\n successCallback = () => {};\n }\n\n if (!errorCallback) {\n errorCallback = () => {};\n }\n\n return context.decodeAudioData(arraybuffer, successCallback, errorCallback);\n}\n\n/**\n * This class (static) method queries browser permission.\n * @param {PermissionName} name This argument is string for `PermissionDescriptor`. For example, this argument is `'microphone'`.\n * @return {Promise<PermissionStatus>} Return value is instance of `Promise` that has instance of `PermissionStatus`.\n */\nexport function permission(name: PermissionName): Promise<PermissionStatus> {\n return navigator.permissions.query({ name });\n};\n\n/**\n * This class (static) method shows designated `Element` in full screen.\n * @param {Element} element This argument is instance of `Element` that is target of full screen.\n * @return {Promise} Return value is instance of `Promise`.\n */\nexport function requestFullscreen(element: Element): Promise<void> {\n return element.requestFullscreen();\n}\n\n/**\n * This class (static) method shows `Document` in original size from full screen.\n * @return {Promise} Return value is instance of `Promise`.\n */\nexport function exitFullscreen(): Promise<void> {\n return document.exitFullscreen();\n}\n\n/**\n * This class (static) method reads file.\n * @property {File} file This argument is instance of `File`.\n * @property {FileReaderType} type This argument is one of 'arraybuffer', 'dataURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n */\nexport function read(params: {\n file: File;\n type: FileReaderType;\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): void {\n const { file, type, successCallback, errorCallback, progressCallback } = params;\n\n const reader = new FileReader();\n\n reader.onprogress = (event: ProgressEvent) => {\n if (progressCallback) {\n progressCallback(event);\n }\n };\n\n reader.onerror = (event: ProgressEvent) => {\n if (!errorCallback) {\n return;\n }\n\n let error: FileReaderErrorText;\n\n switch (reader.error?.code) {\n case reader.error?.NOT_FOUND_ERR: {\n error = 'NOT_FOUND_ERR';\n break;\n }\n\n case reader.error?.SECURITY_ERR: {\n error = 'SECURITY_ERR';\n break;\n }\n\n case reader.error?.ABORT_ERR: {\n error = 'ABORT_ERR';\n break;\n }\n\n case reader.error?.NOT_SUPPORTED_ERR: {\n error = 'NOT_READABLE_ERR';\n break;\n }\n\n default: {\n error = 'ERR';\n break;\n }\n }\n\n errorCallback(event, error);\n };\n\n reader.onload = (event: ProgressEvent) => {\n if (!successCallback) {\n return;\n }\n\n let result = reader.result;\n\n // Escape `<script>` if `FileReaderType` is either `text` or `json`\n switch (type) {\n case 'text': {\n if (typeof result === 'string') {\n result = result.replace(/<(\\/?script.*?)>/gi, '<$1>');\n }\n\n break;\n }\n\n case 'json': {\n if (typeof result === 'string') {\n result = JSON.parse(result.replace(/<(\\/?script.*?)>/gi, '<$1>'));\n }\n\n break;\n }\n }\n\n successCallback(event, result);\n };\n\n switch (type) {\n case 'arraybuffer': {\n reader.readAsArrayBuffer(file);\n break;\n }\n\n case 'dataURL': {\n reader.readAsDataURL(file);\n break;\n }\n\n case 'text':\n case 'json': {\n reader.readAsText(file, 'UTF-8');\n break;\n }\n }\n}\n\n/**\n * This class (static) method gets instance of `File` from `DataTransfer`.\n * @property {DragEvent} event This argument is instance of `DragEvent`.\n * @property {FileReaderType|string} type This argument is one of 'arraybuffer', 'dataURL', 'objectURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n * @return {string|File|null} Return value is Object URL or instance of `File` on success. Otherwise, it is `null`.\n */\nexport function drop(params: {\n event: DragEvent;\n type: FileReaderType | 'objectURL';\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): string | File | null {\n const { event, type, successCallback, errorCallback, progressCallback } = params;\n\n event.preventDefault();\n\n if (!event.dataTransfer?.items[0]) {\n return null;\n }\n\n const file = event.dataTransfer.items[0].getAsFile();\n\n if (file === null) {\n return null;\n }\n\n if (type === 'objectURL') {\n return window.URL.createObjectURL(file);\n }\n\n read({\n file,\n type,\n successCallback,\n errorCallback,\n progressCallback\n });\n\n return file;\n}\n\n/**\n * This class (static) method gets instance of `File`.\n * @property {Event} event This argument is instance of `Event` by `HTMLInputElement`.\n * @property {FileReaderType|string} type This argument is one of 'arraybuffer', 'dataURL', 'objectURL', 'text', 'json'.\n * @property {function} successCallback This argument is invoked on success.\n * @property {function} errorCallback This argument is invoked on failure.\n * @property {function} progressCallback This argument is invoked as `onprogress` event handler in instance of `FileReader`.\n * @return {string|File|null} Return value is Object URL or instance of `File` on success. Otherwise, it is `null`.\n */\nexport function file(params: {\n event: FileEvent;\n type: FileReaderType | 'objectURL';\n successCallback?(event: ProgressEvent, result: ArrayBuffer | ReturnType<typeof JSON.parse> | string | null): void;\n errorCallback?(event: ProgressEvent, textStatus: FileReaderErrorText): void;\n progressCallback?(event: ProgressEvent): void;\n}): string | File | null {\n const { event, type, successCallback, errorCallback, progressCallback } = params;\n\n // HACK:\n const file = event.target.files?.item(0) ?? null;\n\n if (file === null) {\n return null;\n }\n\n if (type === 'objectURL') {\n return window.URL.createObjectURL(file);\n }\n\n read({\n file,\n type,\n successCallback,\n errorCallback,\n progressCallback\n });\n\n return file;\n}\n\n/**\n * This class (static) method calculates frequency from index that corresponds to 12 equal temperament.\n * @param {Array<number>} indexes This argument is array that contains index that corresponds to 12 equal temperament.\n * For example, this value is between 0 and 88 in case of piano.\n * @return {Array<number>} Return value is array that contains frequency.\n */\nexport function toFrequencies(indexes: number[]): number[] {\n return indexes.map((index: number) => computeFrequency(index));\n}\n\n/**\n * This class (static) method creates text file.\n * @param {string} text This argument is string.\n * @param {boolean} asObjectURL This argument is `true` in case of getting text file as Object URL.\n * @return {string} Return value is text file as Data URL or Object URL.\n */\nexport function toTextFile(text: string, asObjectURL: boolean): string {\n if (asObjectURL) {\n const blob = new Blob([text], { type: 'text/plain' });\n\n return window.URL.createObjectURL(blob);\n }\n\n return `data:,${encodeURIComponent(text)}`;\n}\n","/**\n * This class is entity for sequence that has musical note.\n */\nexport class Sequence {\n private _id: string;\n private _note: string;\n private _indexes: number[];\n private _frequencies: number[];\n private _start: number;\n private _stop: number;\n private _duration: number;\n\n /**\n * @property {string} id This argument is string that identifies sequence.\n * @property {string} note This argument is string that corresponds to MML token.\n * @property {Array<number>} indexes This argument is array that contains index that corresponds to 12 equal temperament.\n * @property {Array<number>} frequencies This argument is array that contains frequency.\n * @property {number} start This argument is start time.\n * @property {number} stop This argument is stop time.\n * @property {number} duration This argument is duration.\n */\n constructor(params: {\n id: string;\n note: string;\n indexes: number[];\n frequencies: number[];\n start: number;\n stop: number;\n duration: number;\n }) {\n const { id, note, indexes, frequencies, start, stop, duration } = params;\n\n this._id = id;\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 case of tie.\n * @param {Sequence} sequence This argument is instance of `Sequence`.\n * @return {Sequence} Return value is new instance of `Sequence` that concatenates previous sequence.\n */\n public concat(sequence: Sequence): Sequence {\n return new Sequence({\n id : this._id,\n note : `${this._note}&${sequence.note}`,\n indexes : this._indexes,\n frequencies: this._frequencies,\n start : this._start,\n duration : this._duration + sequence.duration,\n stop : this._start + (this._duration + sequence.duration)\n });\n }\n\n /**\n * This method is getter for musical note as MML token.\n */\n public get note(): string {\n return this._note;\n }\n\n /**\n * This method is getter for array that contains index that corresponds to 12 equal temperament.\n */\n public get indexes(): number[] {\n return this._indexes;\n }\n\n /**\n * This method is getter for array that contains frequency.\n */\n public get frequencies(): number[] {\n return this._frequencies;\n }\n\n /**\n * This method is getter for start time.\n */\n public get start(): number {\n return this._start;\n }\n\n /**\n * This method is getter for stop time.\n */\n public get stop(): number {\n return this._stop;\n }\n\n /**\n * This method is getter for duration,\n */\n public get duration(): number {\n return this._duration;\n }\n\n /**\n * This method returns fields that `Sequence` has as JSON.\n */\n public toString(): string {\n return JSON.stringify({\n id : this._id,\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","import type { Tree } from './Tree';\n\nimport {\n EQUAL_TEMPERAMENT,\n QUARTER_NOTE,\n SHARP,\n HALF_UP,\n HALF_DOWN,\n DOT,\n isPitchChar,\n computeIndex,\n computeFrequency\n} from '../XSound';\nimport { Token } from './Token';\nimport { MMLSyntaxError } from './Tree';\nimport { TreeConstructor } from './TreeConstructor';\nimport { Sequence } from './Sequence';\n\n/**\n * This class converts syntax tree to array that contains musical note.\n */\nexport class Sequencer {\n private sequences: Sequence[] = [];\n private treeConstructor: TreeConstructor;\n private syntaxTree = '';\n\n private timeOf4note = 0;\n private octave = -1;\n private currentTime = 0;\n\n private errorCallback: (error: MMLSyntaxError) => void;\n\n /**\n * @param {TreeConstructor} treeConstructor This argument is instance of `TreeConstructor`.\n * @param {function} errorCallback This argument is invoked on error.\n */\n constructor(treeConstructor: TreeConstructor, errorCallback?: (error: MMLSyntaxError) => void) {\n this.treeConstructor = treeConstructor;\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\n } else {\n this.errorCallback = (error: MMLSyntaxError) => {\n throw error;\n };\n }\n }\n\n /**\n * This method calculates pitch and music time from Parse Tree.\n * @return {Array<Sequence>} Return value is array that contains instance of `Sequence`.\n * If error occurs, error handler is invoked. Return value is `undefined`.\n */\n public get(): Sequence[] | void {\n TreeConstructor.id = 0;\n\n const trees = this.treeConstructor.parse();\n\n if (!trees) {\n this.errorCallback(new MMLSyntaxError(new Token('1', 'UNKNOWN', '')));\n return;\n }\n\n if (trees instanceof MMLSyntaxError) {\n this.errorCallback(trees);\n return;\n }\n\n this.timeOf4note = 0;\n this.octave = -1;\n this.currentTime = 0;\n\n let tree: Tree | null = trees[0];\n\n while (tree !== null) {\n if (!tree) {\n this.errorCallback(new MMLSyntaxError(new Token((this.sequences.length + 1).toString(10), 'UNKNOWN', '')));\n return;\n }\n\n if (tree instanceof MMLSyntaxError) {\n this.errorCallback(tree);\n return;\n }\n\n const operator = tree.operator;\n const type = operator.type;\n\n const left = tree.left;\n\n const value = left !== null ? left.operator.value : -1;\n\n switch (type) {\n case 'TEMPO': {\n if (value <= 0) {\n this.errorCallback(new MMLSyntaxError(operator));\n return;\n }\n\n this.timeOf4note = 60 / value;\n\n tree = tree.right;\n break;\n }\n\n case 'OCTAVE': {\n if (value < 0) {\n this.errorCallback(new MMLSyntaxError(operator));\n return;\n }\n\n this.octave = value;\n\n tree = tree.right;\n break;\n }\n\n case 'NOTE':\n case 'REST':\n case 'TIE' : {\n const r = this.push(type === 'TIE' ? tree.right : tree);\n\n if (r instanceof MMLSyntaxError) {\n this.errorCallback(r);\n return;\n }\n\n if (type === 'TIE') {\n this.concat();\n\n tree = tree.right?.right ?? null;\n } else {\n tree = tree.right;\n }\n\n break;\n }\n\n case 'EOS': {\n tree = tree.right;\n break;\n }\n }\n }\n\n this.syntaxTree = trees[0].toString();\n\n // Release Memory for improving MML performance\n this.treeConstructor.free();\n\n return this.sequences;\n }\n\n /**\n * This method returns string that represents MML syntax tree.\n * @return {string}\n */\n public getSyntaxTree(): string {\n return this.syntaxTree;\n }\n\n /**\n * This method constructs syntax tree.\n * @param {Tree|null} tree This argument is instance of `Tree` that is added to syntax tree.\n */\n private push(tree: Tree | null): Tree | void {\n if (tree === null) {\n return;\n }\n\n const left = tree.left;\n const right = tree.right;\n\n // Not leaf\n if ((left === null) || (right === null)) {\n return;\n }\n\n // Not leaf\n const leftToken = left.operator;\n const rightToken = right.operator;\n\n if ((leftToken === null) && (rightToken === null)) {\n // Traverse tree by recursive call\n this.push(left);\n this.push(right);\n return;\n }\n\n // Leaf\n const token = tree.operator.token;\n const value = leftToken.value;\n const digits = leftToken.token;\n\n const indexes: number[] = [];\n const frequencies: number[] = [];\n\n if (!token) {\n return;\n }\n\n for (let i = 0, len = token.length; i < len; i++) {\n const note = token.charAt(i);\n\n if (!isPitchChar(note)) {\n continue;\n }\n\n let index = computeIndex(this.octave, note);\n\n // Sharp or Flat (Half up or Half down) ?\n switch (token.charAt(i + 1)) {\n case HALF_UP:\n case SHARP : {\n index++;\n i++;\n break;\n }\n\n case HALF_DOWN: {\n index--;\n i++;\n break;\n }\n\n default: {\n // Normal (Natural)\n break;\n }\n }\n\n // in case of chord\n if (index >= indexes[0]) {\n index -= 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 = 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 if (digits) {\n const numberOf4note = QUARTER_NOTE / value;\n\n // Dotted note ?\n if (digits.includes(DOT)) {\n duration += 1.5 * (numberOf4note * this.timeOf4note);\n } else {\n duration += numberOf4note * this.timeOf4note;\n }\n }\n\n break;\n }\n\n case 6: {\n // Triplet of half note\n duration += (2 * this.timeOf4note) / 3;\n break;\n }\n\n case 12: {\n // Triplet of quarter note\n duration += this.timeOf4note / 3;\n break;\n }\n\n case 18: {\n // Nonuplet of half note\n duration += (2 * this.timeOf4note) / 9;\n break;\n }\n\n case 24: {\n // Triplet of 8th note\n duration += (0.5 * this.timeOf4note) / 3;\n break;\n }\n\n case 36: {\n // Nonuplet of quarter note\n duration += this.timeOf4note / 9;\n break;\n }\n\n case 48: {\n // Triplet of 16th note\n duration += (0.25 * this.timeOf4note) / 3;\n break;\n }\n\n case 72: {\n // Nonuplet of 8th note\n duration += (0.5 * this.timeOf4note) / 9;\n break;\n }\n\n case 96: {\n // Triplet of 32th note\n duration += (0.125 * this.timeOf4note) / 3;\n break;\n }\n\n case 144: {\n // Nonuplet of 16th note\n duration += (0.25 * this.timeOf4note) / 9;\n break;\n }\n\n case 192: {\n // Triplet of 64th note\n duration += (0.0625 * this.timeOf4note) / 3;\n break;\n }\n\n default: {\n this.errorCallback(new MMLSyntaxError(leftToken));\n return;\n }\n }\n\n const id = (this.sequences.length + 1).toString(10);\n const note = `${token}${digits}`;\n const start = this.currentTime;\n const stop = start + duration;\n\n this.sequences.push(new Sequence({ id, note, indexes, frequencies, start, stop, duration }));\n\n this.currentTime += duration;\n }\n\n /**\n * This method concatenates previous sequence and current sequence in case of tie.\n */\n private concat(): void {\n const current = this.sequences.pop();\n const previous = this.sequences.pop();\n\n if (previous && current) {\n this.sequences.push(previous.concat(current));\n }\n }\n}\n","export type MMLScheduleWorkerMessageEventType = 'schedule' | 'next' | 'stop';\n\nexport type MMLScheduleWorkerMessageEventData = {\n type: MMLScheduleWorkerMessageEventType,\n duration?: number\n};\n\nexport const schedule = () => {\n let timerId: number | null = null;\n\n self.onmessage = (event: MessageEvent<MMLScheduleWorkerMessageEventData>) => {\n switch (event.data.type) {\n case 'schedule': {\n if (typeof event.data.duration === 'number') {\n timerId = self.setTimeout(() => {\n const message: MMLScheduleWorkerMessageEventData = { type: 'next' };\n\n self.postMessage(message);\n }, (event.data.duration * 1000));\n }\n\n break;\n }\n\n case 'next': {\n break;\n }\n\n case 'stop': {\n if (timerId !== null) {\n self.clearTimeout(timerId);\n self.close();\n timerId = null;\n }\n\n break;\n }\n }\n };\n};\n","import type { MMLSyntaxError } from './Tree';\nimport type { Sequence } from './Sequence';\nimport type { MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './ScheduleWorker';\n\nimport { createWorkerObjectURL } from '../worker';\nimport { OscillatorModule } from '../OscillatorModule';\nimport { OneshotModule } from '../OneshotModule';\nimport { NoiseModule } from '../NoiseModule';\nimport { Tokenizer } from './Tokenizer';\nimport { TreeConstructor } from './TreeConstructor';\nimport { Sequencer } from './Sequencer';\nimport { schedule } from './ScheduleWorker';\n\nexport type {\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData\n};\n\n/**\n * This class starts and stops each MML part.\n */\nexport class Part {\n private sequences: Sequence[] = [];\n private source: OscillatorModule | OneshotModule | NoiseModule;\n private mml: string;\n private syntaxTree: string;\n private previous: Sequence | null = null;\n private scheduleWorker: Worker | null = null;\n private currentIndex = 0;\n private currentPosition = 0;\n private offset = 0;\n private startCallback?(sequence: Sequence, offset?: number): void;\n private stopCallback?(sequence: Sequence, offset?: number): void;\n private endedCallback?(): void;\n private errorCallback?(error: MMLSyntaxError): void;\n\n /**\n * @property {OscillatorModule|OneshotModule|NoiseModule} source This argument selects sound source.\n * @property {string} mml This argument is MML string.\n * @property {number} offset This argument corrects index of one-shot audio.\n * @property {function} startCallback This argument is invoked on start musical note.\n * @property {function} stopCallback This argument is invoked on stop musical note.\n * @property {function} endedCallback This argument is invoked on ended.\n * @property {function} errorCallback This argument is invoked on syntax error.\n */\n constructor(params: {\n source: OscillatorModule | OneshotModule | NoiseModule;\n mml: string;\n offset?: number;\n startCallback?(sequence: Sequence, offset?: number): void;\n stopCallback?(sequence: Sequence, offset?: number): void;\n endedCallback?(): void;\n errorCallback?(error: MMLSyntaxError): void;\n }) {\n const {\n source,\n mml,\n offset,\n startCallback,\n stopCallback,\n endedCallback,\n errorCallback\n } = params;\n\n this.source = source;\n this.mml = mml;\n this.offset = offset ?? 0;\n\n if (startCallback) {\n this.startCallback = startCallback;\n }\n\n if (stopCallback) {\n this.stopCallback = stopCallback;\n }\n\n if (endedCallback) {\n this.endedCallback = endedCallback;\n }\n\n if (errorCallback) {\n this.errorCallback = errorCallback;\n }\n\n const tokenizer = new Tokenizer(mml);\n const treeConstructor = new TreeConstructor(tokenizer);\n const sequencer = new Sequencer(treeConstructor, this.errorCallback);\n const sequences = sequencer.get();\n\n if (sequences) {\n this.sequences = sequences;\n }\n\n this.syntaxTree = sequencer.getSyntaxTree();\n\n const workerObjectURL = createWorkerObjectURL(schedule.toString());\n\n this.scheduleWorker = new Worker(workerObjectURL);\n\n window.URL.revokeObjectURL(workerObjectURL);\n }\n\n /**\n * This method starts MML. Moreover, this method schedules next sequence.\n * @param {boolean} highlight This argument is `true` in case of surrounding by `span.x-highlight` HTML.\n */\n public start(highlight: boolean): void {\n if (this.scheduleWorker === null) {\n return;\n }\n\n if (!this.sequences[this.currentIndex]) {\n this.stop();\n\n if (this.endedCallback) {\n this.endedCallback();\n }\n\n return;\n }\n\n const sequence = this.sequences[this.currentIndex++];\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\n if (this.startCallback) {\n this.startCallback(sequence);\n }\n } else if (this.source instanceof OneshotModule) {\n const indexes = sequence.indexes\n .filter((index: number) => index !== -1)\n .map((index: number) => index + this.offset);\n\n this.source.ready(0, sequence.duration).start(indexes);\n\n if (this.startCallback) {\n this.startCallback(sequence, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.start();\n\n if (this.startCallback) {\n this.startCallback(sequence);\n }\n }\n\n // ref: https://web.dev/audio-scheduling/\n const message: MMLScheduleWorkerMessageEventData = {\n type : 'schedule',\n duration: sequence.duration\n };\n\n this.scheduleWorker.postMessage(message);\n\n this.scheduleWorker.onmessage = (event: MessageEvent<MMLScheduleWorkerMessageEventData>) => {\n if (event.data.type !== 'next') {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n if (this.stopCallback) {\n this.stopCallback(sequence);\n }\n } else if (this.source instanceof OneshotModule) {\n if (this.stopCallback) {\n this.stopCallback(sequence, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(sequence);\n }\n }\n\n // for stopping MML\n this.previous = sequence;\n\n // Start next sequence\n this.start(highlight);\n };\n }\n\n /**\n * This method stops MML.\n */\n public stop(): void {\n if (this.scheduleWorker === null) {\n return;\n }\n\n if (this.previous === null) {\n return;\n }\n\n if (this.source instanceof OscillatorModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(this.previous);\n }\n } else if (this.source instanceof OneshotModule) {\n const indexes = this.previous.indexes\n .filter((index: number) => index !== -1)\n .map((index: number) => index + this.offset);\n\n this.source.stop(indexes);\n\n if (this.stopCallback) {\n this.stopCallback(this.previous, this.offset);\n }\n } else if (this.source instanceof NoiseModule) {\n this.source.stop();\n\n if (this.stopCallback) {\n this.stopCallback(this.previous);\n }\n }\n\n const message: MMLScheduleWorkerMessageEventData = { type: 'stop' };\n\n this.scheduleWorker.postMessage(message);\n this.scheduleWorker.terminate();\n this.scheduleWorker = null;\n }\n\n /**\n * This method is getter for MML string.\n */\n public getMML(): string {\n return this.mml;\n }\n\n /**\n * This method is getter for array that contains sequence.\n */\n public getSequences(): Sequence[] {\n return this.sequences;\n }\n\n /**\n * This method is getter for string that represents MML syntax tree.\n */\n public getSyntaxTree(): string {\n return this.syntaxTree;\n }\n\n /**\n * This method determines whether sequence exists.\n * @return {boolean} If sequence exists, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return this.sequences.length > 0;\n }\n\n /**\n * This method determines whether MML part is paused.\n * @return {boolean} If MML part are paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return this.scheduleWorker === null;\n }\n\n /**\n * This method is getter for current sequence index.\n */\n public getCurrentIndex(): number {\n return this.currentIndex;\n }\n\n /**\n * This method is setter for current sequence index.\n * @param {number} index This argument is new sequence index.\n */\n public setCurrentIndex(index: number): void {\n if (index >= 0 && index < this.sequences.length) {\n this.currentIndex = index;\n }\n }\n}\n","import type { OscillatorModule } from '../OscillatorModule';\nimport type { OneshotModule } from '../OneshotModule';\nimport type { NoiseModule } from '../NoiseModule';\nimport type { TokenType, TokenMap, Token } from './Token';\nimport type { Tree, MMLSyntaxError } from './Tree';\nimport type { Sequence } from './Sequence';\nimport type { MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './Part';\n\nimport { Part } from './Part';\n\nexport type {\n Part,\n Sequence,\n MMLSyntaxError,\n Tree,\n TokenType,\n TokenMap,\n Token,\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData\n};\n\n/**\n * This class manages instance of `Part` for playing MML (Music Macro Language).\n */\nexport class MML {\n private parts: Part[] = [];\n\n private startCallback?(sequence: Sequence, offset?: number): void;\n private stopCallback?(sequence: Sequence, offset?: number): void;\n private endedCallback?(): void;\n private errorCallback?(error: MMLSyntaxError): void;\n\n // eslint-disable-next-line no-useless-constructor\n constructor() {\n }\n\n /**\n * @property {function} startCallback This argument is invoked on starting MML.\n * @property {function} stopCallback This argument is invoked on stopping MML.\n * @property {function} endedCallback This argument is invoked on ending MML.\n * @property {function} errorCallback This argument is invoked on occurring MML syntax error.\n */\n public setup(callbacks?: {\n startCallback?(sequence: Sequence, offset?: number): void;\n stopCallback?(sequence: Sequence, offset?: number): void;\n endedCallback?(): void;\n errorCallback?(error: MMLSyntaxError): void;\n }): MML {\n if (callbacks?.startCallback) {\n this.startCallback = callbacks.startCallback;\n }\n\n if (callbacks?.stopCallback) {\n this.stopCallback = callbacks.stopCallback;\n }\n\n if (callbacks?.endedCallback) {\n this.endedCallback = callbacks.endedCallback;\n }\n\n if (callbacks?.errorCallback) {\n this.errorCallback = callbacks.errorCallback;\n }\n\n return this;\n }\n\n /**\n * This method parses MML string.\n * @property {OscillatorModule|OneshotModule|NoiseModule} source This argument selects sound source.\n * @property {Array<string>} mmls This argument is MML strings.\n * @property {number} offset This argument is in order to adjust index of one-shot audio.\n * @return {MML} Return value is for method chain.\n */\n public ready(params: {\n source: OscillatorModule | OneshotModule | NoiseModule;\n mmls: string[];\n offset?: number;\n }): MML {\n const { source, mmls, offset } = params;\n\n this.stop();\n this.clear();\n\n const startCallback = this.startCallback;\n const stopCallback = this.stopCallback;\n const endedCallback = this.endedCallback;\n const errorCallback = this.errorCallback;\n\n for (const mml of mmls) {\n this.parts.push(new Part({\n source,\n mml,\n offset,\n startCallback,\n stopCallback,\n endedCallback,\n errorCallback\n }));\n }\n\n return this;\n }\n\n /**\n * This method starts designated MML part. Moreover, this method schedules next sequence.\n * @param {number} partNumber This argument is part of MML.\n * @param {boolean} highlight This argument is `true` in case of surrounding by `span.x-highlight` HTML. The default value is `false`.\n * @return {MML} Return value is for method chain.\n */\n public start(partNumber: number, highlight?: boolean): MML {\n if ((partNumber >= 0) && (partNumber < this.parts.length)) {\n const part = this.parts[partNumber];\n\n part.start(highlight ?? false);\n }\n\n return this;\n }\n\n /**\n * This method stops the all of MML parts.\n * @return {MML} Return value is for method chain.\n */\n public stop(): MML {\n for (const part of this.parts) {\n part.stop();\n }\n\n return this;\n }\n\n /**\n * This method gets MML string.\n * @param {number} index This argument selects MML part.\n * @return {string}\n */\n public getMML(index: number): string {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getMML();\n }\n\n return '';\n }\n\n /**\n * This method gets array that contains MML string.\n * @return {Array<string>}\n */\n public getMMLs(): string[] {\n return this.parts.map((part: Part) => part.getMML());\n }\n\n /**\n * This method determines whether sequences exist.\n * @return {boolean} If sequences exist, this value is `true`. Otherwise, this value is `false`.\n */\n public has(): boolean {\n return (this.parts.length > 0) && this.parts.every((part: Part) => part.has());\n }\n\n /**\n * This method gets array that contains instance of `Sequence`.\n * @param {number} index This argument selects MML part.\n * @return {Array<Sequence>}\n */\n public getSequences(index: number): Sequence[] {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getSequences();\n }\n\n return [];\n }\n\n /**\n * This method gets array that contains instance of `Sequence` from the all of MML parts.\n * @return {Array<Array<Sequence>>}\n */\n public getAllSequences(): Sequence[][] {\n return this.parts.map((part: Part) => part.getSequences());\n }\n\n\n /**\n * This method gets string that represents MML syntax tree.\n * @param {number} index This argument selects MML part.\n * @return {string}\n */\n public getSyntaxTree(index: number): string {\n if ((index >= 0) && (index < this.parts.length)) {\n return this.parts[index].getSyntaxTree();\n }\n\n return '';\n }\n\n /**\n * This method determines whether MMLs are paused.\n * @return {boolean} If MMLs are paused, this value is `true`. Otherwise, this value is `false`.\n */\n public paused(): boolean {\n return (this.parts.length === 0) || this.parts.every((part: Part) => part.paused());\n }\n\n /**\n * This method gets or sets current sequence index.\n * This method is overloaded for type interface and type check.\n * @param {number} partNumber This argument is part of MML.\n * @param {number} sequenceIndex This argument is sequence index.\n * If this argument is omitted, this method is getter for current sequence index.\n * @return {number|MML} Return value is for current sequence index. Otherwise, Return value is for method chain.\n */\n public currentIndex(partNumber: number): number;\n public currentIndex(partNumber: number, sequenceIndex: number): MML;\n public currentIndex(partNumber: number, sequenceIndex?: number): number | MML {\n if ((partNumber < 0) || (partNumber >= this.parts.length)) {\n return this;\n }\n\n if (sequenceIndex) {\n this.parts[partNumber].setCurrentIndex(sequenceIndex);\n return this;\n }\n\n return this.parts[partNumber].getCurrentIndex();\n }\n\n /**\n * This method clears instance of `Part`.\n * @return {MML} Return value is for method chain.\n */\n public clear(): MML {\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 /**\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 public toABC(mml: string, X?: number, T?: string, M?: string, L?: string, K?: string): string {\n // TODO: Refactor to use syntax tree\n\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 (!note) {\n return abc;\n }\n\n if (/T\\d+/i.test(note)) {\n const Q = Number(note.slice(1));\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 = Number(note.slice(1));\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.includes('&')) {\n splittedNotes = note.split('&');\n } else {\n splittedNotes = [note];\n }\n\n let chord = '';\n\n while (splittedNotes.length > 0) {\n const splittedNote = splittedNotes.shift();\n\n if (!splittedNote) {\n return abc;\n }\n\n const duration = Number(splittedNote.replace(/^.+?(\\d+)\\.*$/, '$1'));\n\n let n = '';\n let d = 0;\n\n switch (duration) {\n case 1: {\n n = splittedNote.replace('1', '256');\n break;\n }\n\n case 2: {\n n = splittedNote.replace('2', '128');\n break;\n }\n\n case 4: {\n n = splittedNote.replace('4', '64');\n break;\n }\n\n case 8: {\n n = splittedNote.replace('8', '32');\n break;\n }\n\n case 16: {\n n = splittedNote.replace('16', '16');\n break;\n }\n\n case 32: {\n n = splittedNote.replace('32', '8');\n break;\n }\n\n case 64: {\n n = splittedNote.replace('64', '4');\n break;\n }\n\n case 128: {\n n = splittedNote.replace('128', '2');\n break;\n }\n\n case 256: {\n n = splittedNote.replace('256', '1');\n break;\n }\n\n // Tuplet\n case 6: {\n n = `(3${splittedNote.replace('6', '128')}`;\n d = 128 / 3;\n break;\n }\n\n case 12: {\n n = `(3${splittedNote.replace('12', '64')}`;\n d = 64 / 3;\n break;\n }\n\n case 18: {\n n = `(9${splittedNote.replace('18', '128')}`;\n d = 128 / 9;\n break;\n }\n\n case 24: {\n n = `(3${splittedNote.replace('24', '32')}`;\n d = 32 / 3;\n break;\n }\n\n case 36: {\n n = `(9${splittedNote.replace('36', '64')}`;\n d = 64 / 9;\n break;\n }\n\n case 48: {\n n = `(3${splittedNote.replace('48', '16')}`;\n d = 16 / 3;\n break;\n }\n\n case 72: {\n n = `(9${splittedNote.replace('72', '32')}`;\n d = 32 / 9;\n break;\n }\n\n case 96: {\n n = `(3${splittedNote.replace('96', '8')}`;\n d = 8 / 3;\n break;\n }\n\n case 144: {\n n = `(9${splittedNote.replace('144', '16')}`;\n d = 16 / 9;\n break;\n }\n\n case 192: {\n n = `(3${splittedNote.replace('192', '4')}`;\n d = 4 / 3;\n break;\n }\n\n default: {\n return abc;\n }\n }\n\n if (n.includes('.')) {\n n = n.replace(/^(.+?)\\d+\\.+$/, `$1${1.5 * Number(n.replace(/^.+?(\\d+)\\.+$/, '$1'))}`);\n }\n\n if (n.includes('(')) {\n totalDuration += Number(n.replace(/^.+?(\\d+)\\.*$/i, '$1'));\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 }\n\n case 1: {\n o = ',,,';\n break;\n }\n\n case 2: {\n o = ',,';\n break;\n }\n\n case 3: {\n o = ',';\n break;\n }\n\n case 5: {\n o = '\\'';\n break;\n }\n\n case 6: {\n o = '\\'\\'';\n break;\n }\n\n case 7: {\n o = '\\'\\'\\'';\n break;\n }\n\n case 4 :\n default: {\n break;\n }\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","'use strict';\n\nimport type { SoundModule, SoundModuleParams, Module, ModuleName } from './SoundModule';\nimport type { OscillatorModuleParams, Glide, GlideParams, GlideType, Oscillator, OscillatorParams, OscillatorCustomType } from './OscillatorModule';\nimport type { OneshotModuleParams, OneshotSetting, OneshotSettings, OneshotErrorText } from './OneshotModule';\nimport type { NoiseModuleParams, NoiseType } from './NoiseModule';\nimport type { AudioModuleParams, AudioBufferSprite } from './AudioModule';\nimport type { MediaModuleParams } from './MediaModule';\nimport type { StreamModuleParams, MediaStreamTrackAudioSourceNode } from './StreamModule';\nimport type { Part, Sequence, MMLSyntaxError, Tree, TokenType, TokenMap, Token, MMLScheduleWorkerMessageEventType, MMLScheduleWorkerMessageEventData } from './MML';\nimport type {\n AnalyserParams,\n Domain,\n DataType,\n FFTSize,\n Visualizer,\n VisualizerParams,\n Color,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n CurrentTimeStyles,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams\n} from './SoundModule/Analyser';\nimport type { RecorderParams, RecordType, QuantizationBit, WaveExportType, Frame, Channel, RecorderProcessorMessageEventData } from './SoundModule/Recorder';\nimport type { AutopannerParams } from './SoundModule/Effectors/Autopanner';\nimport type { BitCrusherParams } from './SoundModule/Effectors/BitCrusher';\nimport type { ChorusParams } from './SoundModule/Effectors/Chorus';\nimport type { CompressorParams } from './SoundModule/Effectors/Compressor';\nimport type { DelayParams } from './SoundModule/Effectors/Delay';\nimport type { EnvelopeGenerator, EnvelopeGeneratorParams } from './SoundModule/Effectors/EnvelopeGenerator';\nimport type { EqualizerParams } from './SoundModule/Effectors/Equalizer';\nimport type { FilterParams } from './SoundModule/Effectors/Filter';\nimport type { FlangerParams } from './SoundModule/Effectors/Flanger';\nimport type { FuzzParams } from './SoundModule/Effectors/Fuzz';\nimport type { ListenerParams } from './SoundModule/Effectors/Listener';\nimport type { NoiseGateParams } from './SoundModule/Effectors/NoiseGate';\nimport type { NoiseSuppressorParams } from './SoundModule/Effectors/NoiseSuppressor';\nimport type { OverDriveParams } from './SoundModule/Effectors/OverDrive';\nimport type { PannerParams, Position3D } from './SoundModule/Effectors/Panner';\nimport type { PhaserParams, PhaserNumberOfStages } from './SoundModule/Effectors/Phaser';\nimport type { PitchShifterParams } from './SoundModule/Effectors/PitchShifter';\nimport type { PreampParams, PreampType, PreampCurve } from './SoundModule/Effectors/Preamp';\nimport type {\n Marshall,\n MarshallParams,\n PreEqualizerParams as MarshallPreEqualizerParams,\n PostEqualizerParams as MarshallPostEqualizerParams\n} from './SoundModule/Effectors/Preamps/Marshall';\nimport type {\n MesaBoogie,\n MesaBoogieParams,\n PreEqualizerParams as MesaBoogiePreEqualizerParams,\n PostEqualizerParams as MesaBoogiePostEqualizerParams\n} from './SoundModule/Effectors/Preamps/MesaBoogie';\nimport type {\n Fender,\n FenderParams,\n PreEqualizerParams as FenderPreEqualizerParams,\n PostFilterParams as FenderPostFilterParams,\n SpeakerInches as FenderSpeakerInches\n} from './SoundModule/Effectors/Preamps/Fender';\nimport type { CabinetParams } from './SoundModule/Effectors/Preamps/Cabinet';\nimport type { ReverbParams, ReverbErrorText } from './SoundModule/Effectors/Reverb';\nimport type { RingmodulatorParams } from './SoundModule/Effectors/Ringmodulator';\nimport type { StereoParams } from './SoundModule/Effectors/Stereo';\nimport type { TremoloParams } from './SoundModule/Effectors/Tremolo';\nimport type { VocalCancelerParams, VocalCancelerAlgorithm } from './SoundModule/Effectors/VocalCanceler';\nimport type { WahParams } from './SoundModule/Effectors/Wah';\nimport type { PitchChar, ConvertedTime, FileEvent, FileReaderType, FileReaderErrorText, WindowFunction } from './XSound';\nimport type { FrozenArray, Inputs, Outputs, Parameters } from './worklet';\n\nimport './types';\nimport { SoundModuleProcessor } from './SoundModule';\nimport { OscillatorModule, OscillatorModuleProcessor } from './OscillatorModule';\nimport { OneshotModule, OneshotModuleProcessor } from './OneshotModule';\nimport { NoiseModule, NoiseModuleProcessor } from './NoiseModule';\nimport { AudioModule, AudioModuleProcessor } from './AudioModule';\nimport { MediaModule, MediaModuleProcessor } from './MediaModule';\nimport { StreamModule, StreamModuleProcessor } from './StreamModule';\nimport { ProcessorModule } from './ProcessorModule';\nimport { MixerModule, MixerModuleProcessor } from './MixerModule';\nimport { MIDI } from './MIDI';\nimport { MML } from './MML';\nimport { Analyser } from './SoundModule/Analyser';\nimport { Recorder, RecorderProcessor } from './SoundModule/Recorder';\nimport { Effector } from './SoundModule/Effectors/Effector';\nimport { Autopanner } from './SoundModule/Effectors/Autopanner';\nimport { BitCrusher } from './SoundModule/Effectors/BitCrusher';\nimport { Chorus } from './SoundModule/Effectors/Chorus';\nimport { Compressor } from './SoundModule/Effectors/Compressor';\nimport { Delay } from './SoundModule/Effectors/Delay';\nimport { Equalizer } from './SoundModule/Effectors/Equalizer';\nimport { Filter } from './SoundModule/Effectors/Filter';\nimport { Flanger } from './SoundModule/Effectors/Flanger';\nimport { Fuzz } from './SoundModule/Effectors/Fuzz';\nimport { Listener } from './SoundModule/Effectors/Listener';\nimport { NoiseGate } from './SoundModule/Effectors/NoiseGate';\nimport { NoiseSuppressor } from './SoundModule/Effectors/NoiseSuppressor';\nimport { OverDrive } from './SoundModule/Effectors/OverDrive';\nimport { Panner } from './SoundModule/Effectors/Panner';\nimport { Phaser } from './SoundModule/Effectors/Phaser';\nimport { PitchShifter } from './SoundModule/Effectors/PitchShifter';\nimport { Preamp } from './SoundModule/Effectors/Preamp';\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 { VocalCanceler } from './SoundModule/Effectors/VocalCanceler';\nimport { Wah } from './SoundModule/Effectors/Wah';\nimport { NoiseGateProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/NoiseGateProcessor';\nimport { NoiseSuppressorProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/NoiseSuppressorProcessor';\nimport { PitchShifterProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/PitchShifterProcessor';\nimport { VocalCancelerProcessor } from './SoundModule/Effectors/AudioWorkletProcessors/VocalCancelerProcessor';\nimport {\n EQUAL_TEMPERAMENT,\n FREQUENCY_RATIO,\n MIN_A,\n QUARTER_NOTE,\n HALF_UP,\n HALF_DOWN,\n DOT,\n isPitchChar,\n computeIndex,\n computeFrequency,\n computeHz,\n computePlaybackRate,\n windowFunction,\n fft,\n ifft,\n ajax,\n convertTime,\n decode,\n permission,\n requestFullscreen,\n exitFullscreen,\n read,\n drop,\n file,\n toFrequencies,\n toTextFile\n} from './XSound';\nimport { addAudioWorklet } from './worklet';\n\nexport type Source = OscillatorModule | OneshotModule | NoiseModule | AudioModule | MediaModule | StreamModule | ProcessorModule | MixerModule | Analyser | MIDI | MML;\nexport type SourceName = 'oscillator' | 'oneshot' | 'noise' | 'audio' | 'media' | 'stream' | 'processor' | 'mixer' | 'analyser' | 'midi' | 'mml';\n\n// for legacy browsers\nwindow.AudioContext = window.AudioContext || window.webkitAudioContext;\nwindow.URL = window.URL || window.webkitURL;\n\nconst audiocontext = new AudioContext();\n\n// Memoize instance\nconst sources: { [sourceName: string]: Source | null } = {\n oscillator: null,\n oneshot : null,\n noise : null,\n audio : null,\n media : null,\n stream : null,\n processor : null,\n mixer : null,\n analyser : null,\n midi : null,\n mml : null\n};\n\nconst promise = Promise\n .all([\n addAudioWorklet(audiocontext, SoundModuleProcessor),\n addAudioWorklet(audiocontext, RecorderProcessor),\n addAudioWorklet(audiocontext, OscillatorModuleProcessor),\n addAudioWorklet(audiocontext, OneshotModuleProcessor),\n addAudioWorklet(audiocontext, NoiseModuleProcessor),\n addAudioWorklet(audiocontext, AudioModuleProcessor),\n addAudioWorklet(audiocontext, MediaModuleProcessor),\n addAudioWorklet(audiocontext, StreamModuleProcessor),\n addAudioWorklet(audiocontext, MixerModuleProcessor),\n addAudioWorklet(audiocontext, NoiseGateProcessor),\n addAudioWorklet(audiocontext, NoiseSuppressorProcessor),\n addAudioWorklet(audiocontext, PitchShifterProcessor),\n addAudioWorklet(audiocontext, VocalCancelerProcessor)\n ])\n .then(() => {\n sources.oscillator = new OscillatorModule(audiocontext);\n sources.oneshot = new OneshotModule(audiocontext);\n sources.noise = new NoiseModule(audiocontext);\n sources.audio = new AudioModule(audiocontext);\n sources.media = new MediaModule(audiocontext);\n sources.stream = new StreamModule(audiocontext);\n sources.processor = new ProcessorModule(audiocontext);\n sources.mixer = new MixerModule(audiocontext);\n sources.analyser = new Analyser(audiocontext);\n sources.midi = new MIDI();\n sources.mml = new MML();\n\n return sources;\n })\n .catch((error: Error) => {\n return error;\n });\n\n/**\n * This function gets instance of `Source`.\n * This functions is overloaded for type interface and type check.\n * @param {SourceName|string} sourceName This argument selects instance for sound source.\n * @return {Source|null}\n */\nfunction XSound(sourceName: 'oscillator'): OscillatorModule;\nfunction XSound(sourceName: 'oneshot'): OneshotModule;\nfunction XSound(sourceName: 'noise'): NoiseModule;\nfunction XSound(sourceName: 'audio'): AudioModule;\nfunction XSound(sourceName: 'media'): MediaModule;\nfunction XSound(sourceName: 'stream'): StreamModule;\nfunction XSound(sourceName: 'processor'): ProcessorModule;\nfunction XSound(sourceName: 'mixer'): MixerModule;\nfunction XSound(sourceName: 'analyser'): Analyser;\nfunction XSound(sourceName: 'midi'): MIDI;\nfunction XSound(sourceName: 'mml'): MML;\nfunction XSound(sourecName: string): Source | null {\n switch (sourecName) {\n case 'oscillator': {\n return sources.oscillator;\n }\n\n case 'oneshot': {\n return sources.oneshot;\n }\n\n case 'noise': {\n return sources.noise;\n }\n\n case 'audio': {\n return sources.audio;\n }\n\n case 'media': {\n return sources.media;\n }\n\n case 'stream': {\n return sources.stream;\n }\n\n case 'processor': {\n return sources.processor;\n }\n\n case 'mixer': {\n return sources.mixer;\n }\n\n case 'analyser': {\n return sources.analyser;\n }\n\n case 'midi': {\n return sources.midi;\n }\n\n case 'mml': {\n return sources.mml;\n }\n\n default: {\n return null;\n }\n }\n}\n\n/**\n * Class (Static) properties\n */\nXSound.SAMPLE_RATE = audiocontext.sampleRate;\nXSound.EQUAL_TEMPERAMENT = EQUAL_TEMPERAMENT;\nXSound.FREQUENCY_RATIO = FREQUENCY_RATIO;\nXSound.MIN_A = MIN_A;\nXSound.QUARTER_NOT = QUARTER_NOTE;\nXSound.HALF_UP = HALF_UP;\nXSound.HALF_DOWN = HALF_DOWN;\nXSound.DOT = DOT;\nXSound.isPitchChar = isPitchChar;\nXSound.computeIndex = computeIndex;\nXSound.computeHz = computeHz;\nXSound.computeFrequency = computeFrequency;\nXSound.computePlaybackRate = computePlaybackRate;\nXSound.windowFunction = windowFunction;\nXSound.fft = fft;\nXSound.ifft = ifft;\nXSound.ajax = ajax;\nXSound.convertTime = convertTime;\nXSound.decode = decode;\nXSound.permission = permission;\nXSound.requestFullscreen = requestFullscreen;\nXSound.exitFullscreen = exitFullscreen;\nXSound.read = read;\nXSound.drop = drop;\nXSound.file = file;\nXSound.toFrequencies = toFrequencies;\nXSound.toTextFile = toTextFile;\n\n// Export classes\nXSound.Analyser = Analyser;\nXSound.Recorder = Recorder;\n\nXSound.Effector = Effector;\nXSound.Autopanner = Autopanner;\nXSound.BitCrusher = BitCrusher;\nXSound.Chorus = Chorus;\nXSound.Compressor = Compressor;\nXSound.Delay = Delay;\nXSound.Equalizer = Equalizer;\nXSound.Filter = Filter;\nXSound.Flanger = Flanger;\nXSound.Fuzz = Fuzz;\nXSound.Listener = Listener;\nXSound.NoiseGate = NoiseGate;\nXSound.NoiseSuppressor = NoiseSuppressor;\nXSound.OverDrive = OverDrive;\nXSound.Panner = Panner;\nXSound.Phaser = Phaser;\nXSound.PitchShifter = PitchShifter;\nXSound.Preamp = Preamp;\nXSound.Reverb = Reverb;\nXSound.Ringmodulator = Ringmodulator;\nXSound.Stereo = Stereo;\nXSound.Tremolo = Tremolo;\nXSound.VocalCanceler = VocalCanceler;\nXSound.Wah = Wah;\n\n/**\n * This class (static) method changes `AudioContextState` to 'running'.\n * Initial state is 'suspended' by Autoplay Policy.\n * Therefore, this method must be invoked by user gestures.\n * @return {Promise<void>} Return value is `Promise`.\n */\nXSound.setup = (): Promise<void> => {\n if (audiocontext.state !== 'running') {\n return audiocontext.resume();\n }\n\n return Promise.resolve();\n};\n\n/**\n * This class (static) method returns `Promise` that waits instantiating `AudioWorkletProcessor`s.\n * @return {Promise<Source|null|Error>} Return value is `Promise`.\n */\nXSound.promise = (): Promise<typeof sources | Error> => {\n return promise;\n};\n\n/**\n * This class (static) method returns closure that gets cloned instance of `Source`.\n * @return {function}\n */\nXSound.clone = (): typeof ClonedXSound => {\n const clonedSources: { [sourceName: string]: Source | null } = {\n oscillator: null,\n oneshot : null,\n noise : null,\n audio : null,\n media : null,\n stream : null,\n processor : null,\n mixer : null,\n analyser : null,\n midi : null,\n mml : null\n };\n\n function ClonedXSound(sourceName: 'oscillator'): OscillatorModule;\n function ClonedXSound(sourceName: 'oneshot'): OneshotModule;\n function ClonedXSound(sourceName: 'noise'): NoiseModule;\n function ClonedXSound(sourceName: 'audio'): AudioModule;\n function ClonedXSound(sourceName: 'media'): MediaModule;\n function ClonedXSound(sourceName: 'stream'): StreamModule;\n function ClonedXSound(sourceName: 'processor'): ProcessorModule;\n function ClonedXSound(sourceName: 'mixer'): MixerModule;\n function ClonedXSound(sourceName: 'analyser'): Analyser;\n function ClonedXSound(sourceName: 'midi'): MIDI;\n function ClonedXSound(sourceName: 'mml'): MML;\n function ClonedXSound(sourecName: string): Source | null {\n switch (sourecName) {\n case 'oscillator': {\n return clonedSources.oscillator;\n }\n\n case 'oneshot': {\n return clonedSources.oneshot;\n }\n\n case 'noise': {\n return clonedSources.noise;\n }\n\n case 'audio': {\n return clonedSources.audio;\n }\n\n case 'media': {\n return clonedSources.media;\n }\n\n case 'stream': {\n return clonedSources.stream;\n }\n\n case 'processor': {\n return clonedSources.processor;\n }\n\n case 'mixer': {\n return clonedSources.mixer;\n }\n\n case 'analyser': {\n return clonedSources.analyser;\n }\n\n case 'midi': {\n return clonedSources.midi;\n }\n\n case 'mml': {\n return clonedSources.mml;\n }\n\n default: {\n return null;\n }\n }\n }\n\n ClonedXSound.free = (unusedSources: Source[]): void => {\n for (const unusedSource of unusedSources) {\n // Already deleted ?\n if (unusedSource === null) {\n continue;\n }\n\n Object.entries(clonedSources).forEach(([sourceName, clonedSource]: [string, Source | null]) => {\n if (unusedSource === clonedSource) {\n clonedSources[sourceName] = null;\n }\n });\n }\n };\n\n clonedSources.oscillator = new OscillatorModule(audiocontext);\n clonedSources.oneshot = new OneshotModule(audiocontext);\n clonedSources.noise = new NoiseModule(audiocontext);\n clonedSources.audio = new AudioModule(audiocontext);\n clonedSources.media = new MediaModule(audiocontext);\n clonedSources.stream = new StreamModule(audiocontext);\n clonedSources.processor = new ProcessorModule(audiocontext);\n clonedSources.mixer = new MixerModule(audiocontext);\n clonedSources.analyser = new Analyser(audiocontext);\n clonedSources.midi = new MIDI();\n clonedSources.mml = new MML();\n\n // Closure\n return ClonedXSound;\n};\n\n/**\n * This class (static) method releases memory of unused instances.\n * @param {Array<Source>} unusedSources This argument is array that contains unused instance of `Source`.\n */\nXSound.free = (unusedSources: Source[]): void => {\n for (const unusedSource of unusedSources) {\n // Already deleted ?\n if (unusedSource === null) {\n continue;\n }\n\n Object.entries(sources).forEach(([sourceName, memoizedSource]: [string, Source | null]) => {\n if (unusedSource === memoizedSource) {\n sources[sourceName] = null; // Release heap\n }\n });\n }\n};\n\n/**\n * This method deletes `XSound` function as global object.\n * @param {boolean} deep This argument selects whether deleting both of global objects.\n * If this value is `true`, both of global objects are deleted.\n * @return {XSound}\n */\nXSound.noConflict = (deep: boolean): typeof XSound => {\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 instance of `AudioContext`.\n * @return {AudioContext}\n */\nXSound.get = (): AudioContext => {\n return audiocontext;\n};\n\n/**\n * This class (static) method gets elapsed time from creating instance of `AudioContext`.\n * @return {number}\n */\nXSound.getCurrentTime = (): number => {\n return audiocontext.currentTime;\n};\n\nconst setup = (event: MouseEvent | TouchEvent): void => {\n event.stopImmediatePropagation();\n\n XSound\n .setup()\n .finally(() => {\n document.removeEventListener('mousedown', setup, false);\n document.removeEventListener('touchstart', setup, false);\n });\n};\n\ndocument.addEventListener('mousedown', setup, false);\ndocument.addEventListener('touchstart', setup, false);\n\nexport type {\n SoundModule,\n SoundModuleParams,\n SoundModuleProcessor,\n Module,\n ModuleName,\n OscillatorModule,\n OscillatorModuleParams,\n Glide,\n GlideParams,\n GlideType,\n Oscillator,\n OscillatorParams,\n OscillatorCustomType,\n OscillatorModuleProcessor,\n OneshotModule,\n OneshotModuleParams,\n OneshotSetting,\n OneshotSettings,\n OneshotErrorText,\n OneshotModuleProcessor,\n NoiseModule,\n NoiseModuleParams,\n NoiseType,\n NoiseModuleProcessor,\n AudioModule,\n AudioModuleParams,\n AudioBufferSprite,\n AudioModuleProcessor,\n MediaModule,\n MediaModuleParams,\n MediaModuleProcessor,\n StreamModule,\n StreamModuleParams,\n StreamModuleProcessor,\n MediaStreamTrackAudioSourceNode,\n ProcessorModule,\n MixerModule,\n MixerModuleProcessor,\n MIDI,\n MML,\n Part,\n Sequence,\n MMLSyntaxError,\n Tree,\n TokenType,\n TokenMap,\n Token,\n MMLScheduleWorkerMessageEventType,\n MMLScheduleWorkerMessageEventData,\n Analyser,\n AnalyserParams,\n Domain,\n DataType,\n FFTSize,\n Color,\n Visualizer,\n VisualizerParams,\n GraphicsApi,\n Gradient,\n Gradients,\n Shape,\n Font,\n GraphicsStyles,\n SpectrumScale,\n TimeOverview,\n TimeOverviewParams,\n MouseEventTypes,\n DragMode,\n DragCallbackFunction,\n CurrentTimeStyles,\n Time,\n TimeParams,\n FFT,\n FFTParams,\n Spectrogram,\n SpectrogramParams,\n Recorder,\n RecorderParams,\n RecordType,\n QuantizationBit,\n WaveExportType,\n Frame,\n Channel,\n RecorderProcessor,\n RecorderProcessorMessageEventData,\n Effector,\n Autopanner,\n AutopannerParams,\n BitCrusher,\n BitCrusherParams,\n Chorus,\n ChorusParams,\n Compressor,\n CompressorParams,\n Delay,\n DelayParams,\n EnvelopeGenerator,\n EnvelopeGeneratorParams,\n Equalizer,\n EqualizerParams,\n Filter,\n FilterParams,\n Flanger,\n FlangerParams,\n Fuzz,\n FuzzParams,\n Listener,\n ListenerParams,\n NoiseGate,\n NoiseGateParams,\n NoiseGateProcessor,\n NoiseSuppressor,\n NoiseSuppressorParams,\n NoiseSuppressorProcessor,\n OverDrive,\n OverDriveParams,\n Panner,\n PannerParams,\n Position3D,\n Phaser,\n PhaserParams,\n PhaserNumberOfStages,\n PitchShifter,\n PitchShifterParams,\n PitchShifterProcessor,\n Preamp,\n PreampParams,\n PreampType,\n PreampCurve,\n Marshall,\n MarshallParams,\n MarshallPreEqualizerParams,\n MarshallPostEqualizerParams,\n MesaBoogie,\n MesaBoogieParams,\n MesaBoogiePreEqualizerParams,\n MesaBoogiePostEqualizerParams,\n Fender,\n FenderParams,\n FenderPreEqualizerParams,\n FenderPostFilterParams,\n FenderSpeakerInches,\n CabinetParams,\n Reverb,\n ReverbParams,\n ReverbErrorText,\n Ringmodulator,\n RingmodulatorParams,\n Stereo,\n StereoParams,\n Tremolo,\n TremoloParams,\n VocalCanceler,\n VocalCancelerParams,\n VocalCancelerAlgorithm,\n VocalCancelerProcessor,\n Wah,\n WahParams,\n PitchChar,\n ConvertedTime,\n FileEvent,\n FileReaderType,\n FileReaderErrorText,\n WindowFunction,\n FrozenArray,\n Inputs,\n Outputs,\n Parameters\n};\n\nexport { XSound, XSound as X };\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","AudioWorkletProcessor","port","MessagePort","constructor","_options","OverlapAddProcessor","static","frameSize","hopSize","numberOfOverlaps","inputBuffers","inputBuffersHead","inputBuffersToSend","outputBuffers","outputBuffersToRetrieve","options","super","processorOptions","this","allocateInputChannels","allocateOutputChannels","process","inputs","outputs","parameters","reallocateChannelsIfNeeded","readInputs","shiftInputBuffers","prepareInputBuffersToSend","processOverlapAdd","handleOutputBuffersToRetrieve","writeOutputs","shiftOutputBuffers","inputNumberOfChannels","length","outputNumberOfChannels","numberOfChannels","channelNumber","Float32Array","RENDER_QUANTUM_SIZE","subarray","fill","set","copyWithin","n","addAudioWorklet","context","processor","audioWorklet","addModule","encodeURIComponent","toString","name","createModule","SoundModuleProcessor","input","output","Visualizer","sampleRate","channel","analyser","isActive","graphics","canvas","svg","interval","styles","shape","gradients","offset","color","wave","grid","text","font","family","size","style","weight","width","cap","join","top","right","bottom","left","setup","element","HTMLCanvasElement","getContext","SVGSVGElement","connect","source","AudioNode","OUTPUT","start","data","minDecibels","maxDecibels","visualizeOnCanvas","visualizeBySVG","param","params","entries","clear","clearRect","height","innerHTML","create","mimeType","test","toDataURL","callback","type","quality","toBlob","replace","outerHTML","state","activate","deactivate","visualizeTimeDomainFloat32ArrayOnCanvas","innerWidth","innerHeight","middle","numberOfPlots","lineWidth","lineCap","lineJoin","waveColor","strokeStyle","beginPath","len","x","y","moveTo","lineTo","stroke","upside","gradient","createLinearGradient","addColorStop","fillStyle","fillRect","visualizeTimeDomainFloat32ArrayBySVG","linearGradientId","path","document","createElementNS","XMLNS","d","setAttribute","defs","createSVGLinearGradient","g","appendChild","rect","Math","abs","linearGradient","stop","createFontString","SVG_CURRENT_TIME_CLASS_NAME","SVG_SPRITE_CLASS_NAME","TimeOverview","currentImageData","currentSVGElement","currentDataSize","currentTime","sprite","plotInterval","textInterval","isDown","mode","offsetX","startTime","endTime","onMouseStart","bind","onMouseMove","onMouseUp","onTouchStart","onTouchMove","onTouchEnd","update","time","currentTimeColor","putImageData","baseX","trunc","querySelector","Number","getAttribute","spriteRect","parentNode","removeChild","prevRect","baseRect","classList","add","drag","visualizationNode","removeEventListener","handleEvent","window","addEventListener","_minDecibels","_maxDecibels","Uint8Array","gridColor","textColor","fontSize","parseInt","numberOfTexts","i","t","fillText","measureText","trim","getImageData","SVG_LINEAR_GRADIENT_ID_TIME_OVERVIEW","textContent","visualize","event","offsetLeft","parentElement","scrollLeft","getOffsetX","stopPropagation","preventDefault","MouseEvent","pageX","TouchEvent","touches","Time","timeText","ceil","amplitudeText","SVG_LINEAR_GRADIENT_ID_TIME","FFT","scale","logarithmicFrequencies","minFrequency","maxFrequency","ratio","log10Ratio","log10","Array","isArray","mindB","maxdB","range","actualSize","frequencyResolution","k","frequencyRatio","log10FrequencyRatio","isFinite","frequency","frequencyText","slice","forEach","amplitude","SVG_LINEAR_GRADIENT_ID_FFT","Spectrogram","duration","linearFrequencyTextInterval","timeTextInterval","timeOffset","numberOfSamples","renderSize","imagedata","colorFromNumber","numberToJetColor","rgba","max","min","setColorFromNumberFunction","func","frequencyBinCount","fftSize","samples","textAlign","toFixed","index","h","rectX","rectY","Analyser","analysers","splitter","timeOverviews","times","ffts","spectrograms","timeDomainAnimationIds","timeDomainTimerIds","frequencyDomainAnimationIds","frequencyDomainTimerIds","spectrogramAnimationIds","spectrogramTimerIds","createAnalyser","createChannelSplitter","createGain","smoothingTimeConstant","domain","buffer","undefined","disconnect","getChannelData","getByteTimeDomainData","getFloatTimeDomainData","requestAnimationFrame","setTimeout","getByteFrequencyData","getFloatFrequencyData","animationId","timerId","cancelAnimationFrame","clearTimeout","INPUT","Frame","id","dataBlocks","append","dataBlock","push","has","Channel","frames","channelGain","frame","frameNumber","gain","RecorderProcessor","message","postMessage","Recorder","channels","activeTrack","paused","AudioWorkletNode","onmessage","bufferSize","BUFFER_SIZE","inputLs","gainL","frameL","recordedLs","inputRs","gainR","frameR","recordedRs","numberOfTracks","ready","trackNumber","hasTrack","qbits","soundLs","soundRs","mixTrack","flatTrack","RATE","QBITS","CHANNELS","SAMPLES","SIZE","CHUNK_SIZE","RIFF_CHUNK_SIZE","BPS","DATA_SIZE","sounds","binary","round","Int16Array","base64","btoa","from","map","String","fromCodePoint","blob","Blob","URL","createObjectURL","hasChannel","some","every","flattenTrack","j","sum","numberOfElements","currentBlock","numberOfMaxBlocks","mixedValues","currentFrame","Effector","lfo","depth","rate","createOscillator","stopTime","releaseTime","toJSON","JSON","stringify","Autopanner","panner","createStereoPanner","pan","BitCrusher","shaper","inputShaper","outputShaper","inputLevel","outputLevel","bitsInput","bitsGain","bits","createWaveShaper","createConstantSource","curve","v","inputCurve","outputCurve","oversample","_startTime","_stopTime","_releaseTime","Chorus","delay","tone","dry","wet","feedback","depthRate","createDelay","createBiquadFilter","delayTime","Q","SQRT1_2","mix","Compressor","compressor","createDynamicsCompressor","threshold","knee","attack","release","Delay","MAX_DELAY_TIME","EnvelopeGenerator","generators","activeIndexes","activeCounter","decay","sustain","t0","t1","t2","t2Value","activeIndex","cancelScheduledValues","setValueAtTime","linearRampToValueAtTime","setTargetAtTime","useCurve","s","t3","t4","cancelAndHoldAtTime","setValueCurveAtTime","getGenerator","setGenerator","counter","MIN_GAIN","disconnected","generator","Equalizer","bass","treble","presence","Filter","filter","minFrequnecy","Flanger","Fuzz","positiveShaper","negativeShaper","positiveInputGain","negativeInputGain","positiveOutputGain","negativeOutputGain","outFilter","driveInput","level","drive","r","tanh","Listener","listener","positions","forwards","ups","z","setPosition","setOrientation","fx","fy","fz","ux","uy","uz","NoiseGateProcessor","instance","ArrayBuffer","WebAssembly","instantiate","then","catch","error","wasm","linearMemory","memory","offsetInput","alloc_memory_inputs","offsetOutput","noisegate","NoiseGate","fetch","async","response","arrayBuffer","NoiseSuppressorProcessor","noisesuppressor","NoiseSuppressor","OverDrive","inputGain","outputGain","d1","Panner","orientations","createPanner","refDistance","maxDistance","rolloffFactor","coneInnerAngle","coneOuterAngle","coneOuterGain","panningModel","distanceModel","positionX","positionY","positionZ","orientationX","orientationY","orientationZ","ox","oy","oz","Phaser","numberOfStages","filters","MAX_STAGES","stage","resonance","PitchShifterProcessor","timeCursor","pitch","speed","pitchshifter","shiftedOutput","PitchShifter","Cabinet","lowpass","notch","PreEqualizer","preGain","leadGain","highpass1","highpass2","highpass3","lead","PostEqualizer","highpass","Marshall","preEQ","postEQ","cabinet","createCurve","pre","post","preHighpass","postHighpass","shapers","usePostFilters","postFilters","peakingFilters","fc100","fc360","fc720","fc1600","fc4800","MesaBoogie","gainEdge","gainBody","gainBottom","iirLowpassFilters","iirHighpassFilters","mixer","coefficient1","PI","coefficient2","lowpassFeedforward1","lowpassFeedforward2","lowpassFeedback1","lowpassFeedback2","highpassFeedforward1","highpassFeedforward2","highpassFeedback1","highpassFeedback2","createIIRFilter","PostFilter","inch","tilt","speakerFilter","tiltFilter","Fender","postFilter","curves","c","peak","Preamp","preamp","Reverb","convolver","rirs","loadError","createConvolver","AudioBuffer","impulse","errorCallback","successCallback","decodeAudioData","preset","timeout","progressCallback","rir","load","xhr","XMLHttpRequest","ontimeout","onprogress","abort","onerror","onload","status","decodeSuccessCallback","decodeErrorCallback","open","responseType","send","Ringmodulator","Stereo","merger","createChannelMerger","Tremolo","VocalCancelerProcessor","algorithm","offsetInputL","alloc_memory_inputLs","offsetInputR","alloc_memory_inputRs","inputLinearMemoryL","inputLinearMemoryR","offsetOutputL","vocalcancelerL","offsetOutputR","vocalcancelerR","vocalcanceler_on_spectrum","BYTES_PER_ELEMENT","canceledInputLs","canceledInputRs","VocalCanceler","Wah","auto","envelopeFollower","sensitivity","cutoff","SoundModule","destination","modules","mastervolume","recorder","autopanner","bitcrusher","chorus","envelopegenerator","equalizer","flanger","fuzz","overdrive","phaser","reverb","ringmodulator","stereo","tremolo","vocalcanceler","wah","runningAnalyser","mixed","audioDestination","streamDestination","createMediaStreamDestination","sinkId","setSinkId","install","effector","extendedEffector","on","off","suspend","demix","edit","previousModules","init","OscillatorModuleProcessor","Glide","prevFrequency","nextFrequency","diff","oscillator","exponentialRampToValueAtTime","Oscillator","volume","octave","fine","custom","real","imag","detune","reals","imags","periodicWave","createPeriodicWave","setPeriodicWave","MAX_SIZE","OCTAVE","OscillatorModule","sources","glide","states","frequencies","moduleName","OneshotModuleProcessor","OneshotModule","resources","buffers","volumes","settings","transpose","url","indexes","bufferIndex","playbackRate","loop","loopStart","loopEnd","createBufferSource","reset","paramName","NoiseModuleProcessor","processing","_inputs","whitenoise","pinknoise","browniannoise","NoiseModule","AudioModuleProcessor","AudioModule","stopped","callbacks","decodeCallback","updateCallback","endedCallback","audiobuffer","end","computedPlaybackRate","computePlaybackRate","timeoverviewL","timeoverviewR","fadeIn","fadeOut","dataLs","dataRs","bufferLs","createBuffer","copyToChannel","bufferRs","sprites","keys","reduce","audioSprite","spriteName","MediaModuleProcessor","MediaModule","media","ext","autoplay","mediaSource","sourceBuffer","file","listeners","onSourceOpen","onSourceEnded","onSourceClose","onSourceBufferUpdateEnd","onSourceBufferError","formats","format","audioMime","videoMime","canAudio","canPlayType","canVideo","eventType","createMediaElementSource","pause","src","resume","readyState","endOfStream","revokeObjectURL","MediaSource","isTypeSupported","removeAttribute","startsWith","position","play","muted","controls","isNaN","hasMedia","hasSource","requestPictureInPicture","HTMLVideoElement","pictureInPictureEnabled","disablePictureInPicture","pictureInPictureElement","Promise","reject","exitPictureInPicture","addSourceBuffer","request","Request","appendBuffer","finally","sourceopen","sourceended","sourceclose","updateend","StreamModuleProcessor","StreamModule","stream","constraints","audio","video","track","navigator","mediaDevices","getUserMedia","MediaStream","resolve","audioTracks","getAudioTracks","createMediaStreamTrackSource","createMediaStreamSource","getStream","getConstraints","setConstraints","clearAudioDevices","clearVideoDevices","audioTrack","videoTracks","getVideoTracks","videoTrack","devices","enumerateDevices","streaming","setInputDeviceId","deviceId","audioConstraints","ProcessorModule","processorName","moduleURL","credentials","onMessage","onMessageError","onmessageerror","MixerModuleProcessor","MixerModule","gainNodes","gains","gainNode","MIDI","midiAccess","requestMIDIAccess","extractWorkerString","workerContainerString","createWorkerObjectURL","createWorkerBlob","TokenMap","Map","Token","_id","_type","_token","_value","token","Tokenizer","tokens","notes","numbers","mml","toUpperCase","split","reverse","pop","tokenType","Tree","_operator","_left","_right","operator","concat","node","indent","space","MMLSyntaxError","TreeConstructor","tokenizer","syntaxTree","parse","nextToken","tree","free","FREQUENCY_RATIO","isPitchChar","pitchChar","computeIndex","computedIndex","computeFrequency","read","reader","FileReader","code","NOT_FOUND_ERR","SECURITY_ERR","ABORT_ERR","NOT_SUPPORTED_ERR","result","readAsArrayBuffer","readAsDataURL","readAsText","instantiateStreaming","Sequence","_note","_indexes","_frequencies","_start","_stop","_duration","note","sequence","Sequencer","sequences","treeConstructor","timeOf4note","trees","getSyntaxTree","leftToken","rightToken","digits","charAt","numberOf4note","includes","current","previous","schedule","close","Part","scheduleWorker","currentIndex","currentPosition","startCallback","stopCallback","sequencer","workerObjectURL","Worker","highlight","prev","indexOf","terminate","getMML","getSequences","getCurrentIndex","setCurrentIndex","MML","parts","mmls","partNumber","part","getMMLs","getAllSequences","sequenceIndex","toABC","X","T","M","L","K","abc","match","totalDuration","shift","splittedNotes","chord","splittedNote","matches","tuplet","chordLength","restNote","AudioContext","webkitAudioContext","webkitURL","audiocontext","oneshot","noise","midi","promise","all","XSound","sourecName","SAMPLE_RATE","EQUAL_TEMPERAMENT","MIN_A","QUARTER_NOT","HALF_UP","HALF_DOWN","DOT","computeHz","windowFunction","w","cos","alpha","a0","a1","a2","fft","offsetReal","alloc_memory_reals","offsetImag","alloc_memory_imags","realsLinearMemory","imagsLinearMemory","ifft","IFFT","ajax","convertTime","minutes","seconds","milliseconds","decode","arraybuffer","permission","permissions","query","requestFullscreen","exitFullscreen","drop","dataTransfer","items","getAsFile","target","files","item","toFrequencies","toTextFile","asObjectURL","clone","clonedSources","ClonedXSound","unusedSources","unusedSource","sourceName","clonedSource","memoizedSource","noConflict","deep","getCurrentTime","stopImmediatePropagation"],"ignoreList":[],"sourceRoot":""}
|