{"version":3,"file":"pixi-sound.mjs","sources":["../src/instance.ts","../src/filters/Filter.ts","../src/filters/DistortionFilter.ts","../src/webaudio/WebAudioUtils.ts","../src/filters/EqualizerFilter.ts","../src/filters/MonoFilter.ts","../src/filters/ReverbFilter.ts","../src/filters/StereoFilter.ts","../src/filters/StreamFilter.ts","../src/filters/TelephoneFilter.ts","../src/htmlaudio/HTMLAudioContext.ts","../src/htmlaudio/HTMLAudioInstance.ts","../src/htmlaudio/HTMLAudioMedia.ts","../src/SoundSprite.ts","../src/utils/supported.ts","../src/webaudio/WebAudioInstance.ts","../src/Filterable.ts","../src/webaudio/WebAudioNodes.ts","../src/webaudio/WebAudioMedia.ts","../src/Sound.ts","../src/webaudio/WebAudioContext.ts","../src/SoundLibrary.ts","../src/utils/playOnce.ts","../src/utils/render.ts","../src/utils/sineTone.ts","../src/soundAsset.ts","../src/index.ts"],"sourcesContent":["import { SoundLibrary } from './SoundLibrary';\n\n/**\n * Singleton instance of the SoundLibrary\n */\nlet instance: SoundLibrary;\n\n/**\n * Internal set function for the singleton instance.\n * @ignore\n * @param sound - - Sound library instance\n */\nfunction setInstance(sound: SoundLibrary): SoundLibrary\n{\n    instance = sound;\n\n    return sound;\n}\n\n/**\n * Internal get function for the singleton instance.\n * @ignore\n */\nfunction getInstance(): SoundLibrary\n{\n    return instance;\n}\n\nexport { getInstance, instance, setInstance };\n","/**\n * Represents a single sound element. Can be used to play, pause, etc. sound instances.\n *\n * @memberof filters\n */\nclass Filter\n{\n    /** The node to connect for the filter to the previous filter. */\n    public destination: AudioNode;\n\n    /** The node to connect for the filter to the previous filter. */\n    public source: AudioNode;\n\n    /**\n     * @param {AudioNode} destination - The audio node to use as the destination for the input AudioNode\n     * @param {AudioNode} [source] - Optional output node, defaults to destination node. This is useful\n     *        when creating filters which contains multiple AudioNode elements chained together.\n     */\n    constructor(destination: AudioNode, source?: AudioNode)\n    {\n        this.init(destination, source);\n    }\n\n    /** Reinitialize */\n    protected init(destination: AudioNode, source?: AudioNode): void\n    {\n        this.destination = destination;\n        this.source = source || destination;\n    }\n\n    /**\n     * Connect to the destination.\n     * @param {AudioNode} destination - The destination node to connect the output to\n     */\n    public connect(destination: AudioNode): void\n    {\n        this.source?.connect(destination);\n    }\n\n    /** Completely disconnect filter from destination and source nodes. */\n    public disconnect(): void\n    {\n        this.source?.disconnect();\n    }\n\n    /** Destroy the filter and don't use after this. */\n    public destroy(): void\n    {\n        this.disconnect();\n        this.destination = null;\n        this.source = null;\n    }\n}\n\nexport { Filter };\n","import { getInstance } from '../instance';\nimport { Filter } from './Filter';\n\n/**\n * Filter for adding adding delaynode.\n *\n * @memberof filters\n */\nclass DistortionFilter extends Filter\n{\n    /** The Wave shape node use to distort */\n    private _distortion: WaveShaperNode;\n\n    /** The amount of distoration */\n    private _amount: number;\n\n    /** @param amount - The amount of distoration from 0 to 1. */\n    constructor(amount = 0)\n    {\n        let distortion: WaveShaperNode;\n\n        if (!getInstance().useLegacy)\n        {\n            const { audioContext } = getInstance().context;\n\n            distortion = audioContext.createWaveShaper();\n        }\n\n        super(distortion);\n\n        this._distortion = distortion;\n\n        this.amount = amount;\n    }\n\n    /** The amount of distortion to set. */\n    set amount(value: number)\n    {\n        this._amount = value;\n        if (getInstance().useLegacy)\n        {\n            return;\n        }\n        const scaledValue = value * 1000;\n        const samples = 44100;\n        const curve: Float32Array = new Float32Array(samples);\n        const deg: number = Math.PI / 180;\n\n        let i = 0;\n        let x: number;\n\n        for (; i < samples; ++i)\n        {\n            x = (i * 2 / samples) - 1;\n            curve[i] = (3 + scaledValue) * x * 20 * deg / (Math.PI + (scaledValue * Math.abs(x)));\n        }\n        this._distortion.curve = curve;\n        this._distortion.oversample = '4x';\n    }\n    get amount(): number\n    {\n        return this._amount;\n    }\n\n    public destroy(): void\n    {\n        this._distortion = null;\n        super.destroy();\n    }\n}\n\nexport { DistortionFilter };\n","import { getInstance } from '../instance';\nimport { WebAudioContext } from './WebAudioContext';\n\n/**\n * Internal class for Web Audio abstractions and convenience methods.\n * @memberof webaudio\n */\nclass WebAudioUtils\n{\n    /**\n     * Dezippering is removed in the future Web Audio API, instead\n     * we use the `setValueAtTime` method, however, this is not available\n     * in all environments (e.g., Android webview), so we fallback to the `value` setter.\n     * @param param - AudioNode parameter object\n     * @param value - Value to set\n     * @return The value set\n     */\n    public static setParamValue(param: AudioParam, value: number): number\n    {\n        if (param.setValueAtTime)\n        {\n            const context = getInstance().context as WebAudioContext;\n\n            param.setValueAtTime(value, context.audioContext.currentTime);\n        }\n        else\n        {\n            param.value = value;\n        }\n\n        return value;\n    }\n}\n\nexport { WebAudioUtils };\n","import { getInstance } from '../instance';\nimport { WebAudioUtils } from '../webaudio/WebAudioUtils';\nimport { Filter } from './Filter';\n\ninterface Band\n{\n    f: number;\n    type: string;\n    gain: number;\n}\n\n/**\n * Filter for adding equalizer bands.\n *\n * @memberof filters\n */\nclass EqualizerFilter extends Filter\n{\n    /**\n     * Band at 32 Hz\n     * @readonly\n     */\n    public static readonly F32: number = 32;\n\n    /**\n     * Band at 64 Hz\n     * @readonly\n     */\n    public static readonly F64: number = 64;\n\n    /**\n     * Band at 125 Hz\n     * @readonly\n     */\n    public static readonly F125: number = 125;\n\n    /**\n     * Band at 250 Hz\n     * @readonly\n     */\n    public static readonly F250: number = 250;\n\n    /**\n     * Band at 500 Hz\n     * @readonly\n     */\n    public static readonly F500: number = 500;\n\n    /**\n     * Band at 1000 Hz\n     * @readonly\n     */\n    public static readonly F1K: number = 1000;\n\n    /**\n     * Band at 2000 Hz\n     * @readonly\n     */\n    public static readonly F2K: number = 2000;\n\n    /**\n     * Band at 4000 Hz\n     * @readonly\n     */\n    public static readonly F4K: number = 4000;\n\n    /**\n     * Band at 8000 Hz\n     * @readonly\n     */\n    public static readonly F8K: number = 8000;\n\n    /**\n     * Band at 16000 Hz\n     * @readonly\n     */\n    public static readonly F16K: number = 16000;\n\n    /**\n     * The list of bands\n     * @readonly\n     */\n    public readonly bands: BiquadFilterNode[];\n\n    /**\n     * The map of bands to frequency\n     * @readonly\n     */\n    public readonly bandsMap: Record<number, BiquadFilterNode>;\n\n    /**\n     * @param f32 - Default gain for 32 Hz\n     * @param f64 - Default gain for 64 Hz\n     * @param f125 - Default gain for 125 Hz\n     * @param f250 - Default gain for 250 Hz\n     * @param f500 - Default gain for 500 Hz\n     * @param f1k - Default gain for 1000 Hz\n     * @param f2k - Default gain for 2000 Hz\n     * @param f4k - Default gain for 4000 Hz\n     * @param f8k - Default gain for 8000 Hz\n     * @param f16k - Default gain for 16000 Hz\n     */\n    constructor(f32 = 0, f64 = 0, f125 = 0, f250 = 0, f500 = 0,\n        f1k = 0, f2k = 0, f4k = 0, f8k = 0, f16k = 0)\n    {\n        let bands: BiquadFilterNode[] = [];\n\n        const equalizerBands: Band[] = [\n            {\n                f: EqualizerFilter.F32,\n                type: 'lowshelf',\n                gain: f32,\n            },\n            {\n                f: EqualizerFilter.F64,\n                type: 'peaking',\n                gain: f64,\n            },\n            {\n                f: EqualizerFilter.F125,\n                type: 'peaking',\n                gain: f125,\n            },\n            {\n                f: EqualizerFilter.F250,\n                type: 'peaking',\n                gain: f250,\n            },\n            {\n                f: EqualizerFilter.F500,\n                type: 'peaking',\n                gain: f500,\n            },\n            {\n                f: EqualizerFilter.F1K,\n                type: 'peaking',\n                gain: f1k,\n            },\n            {\n                f: EqualizerFilter.F2K,\n                type: 'peaking',\n                gain: f2k,\n            },\n            {\n                f: EqualizerFilter.F4K,\n                type: 'peaking',\n                gain: f4k,\n            },\n            {\n                f: EqualizerFilter.F8K,\n                type: 'peaking',\n                gain: f8k,\n            },\n            {\n                f: EqualizerFilter.F16K,\n                type: 'highshelf',\n                gain: f16k,\n            },\n        ];\n\n        if (!getInstance().useLegacy)\n        {\n            bands = equalizerBands.map((band: Band) =>\n            {\n                const node: BiquadFilterNode = getInstance().context.audioContext.createBiquadFilter();\n\n                node.type = band.type as BiquadFilterType;\n                WebAudioUtils.setParamValue(node.Q, 1);\n                node.frequency.value = band.f; // WebAudioUtils.setParamValue(filter.frequency, band.f);\n                WebAudioUtils.setParamValue(node.gain, band.gain);\n\n                return node;\n            });\n        }\n\n        // Setup the constructor AudioNode, where first is the input, and last is the output\n        super(bands[0], bands[bands.length - 1]);\n\n        // Manipulate the bands\n        this.bands = bands;\n\n        // Create a map\n        this.bandsMap = {};\n\n        for (let i = 0; i < this.bands.length; i++)\n        {\n            const node: BiquadFilterNode = this.bands[i];\n\n            // Connect the previous band to the current one\n            if (i > 0)\n            {\n                this.bands[i - 1].connect(node);\n            }\n            this.bandsMap[node.frequency.value] = node;\n        }\n    }\n\n    /**\n     * Set gain on a specific frequency.\n     * @param frequency - The frequency, see EqualizerFilter.F* for bands\n     * @param gain - Recommended -40 to 40.\n     */\n    public setGain(frequency: number, gain = 0): void\n    {\n        if (!this.bandsMap[frequency])\n        {\n            throw new Error(`No band found for frequency ${frequency}`);\n        }\n        WebAudioUtils.setParamValue(this.bandsMap[frequency].gain, gain);\n    }\n\n    /**\n     * Get gain amount on a specific frequency.\n     * @return The amount of gain set.\n     */\n    public getGain(frequency: number): number\n    {\n        if (!this.bandsMap[frequency])\n        {\n            throw new Error(`No band found for frequency ${frequency}`);\n        }\n\n        return this.bandsMap[frequency].gain.value;\n    }\n\n    /**\n     * Gain at 32 Hz frequencey.\n     * @default 0\n     */\n    public set f32(value: number)\n    {\n        this.setGain(EqualizerFilter.F32, value);\n    }\n    public get f32(): number\n    {\n        return this.getGain(EqualizerFilter.F32);\n    }\n\n    /**\n     * Gain at 64 Hz frequencey.\n     * @default 0\n     */\n    public set f64(value: number)\n    {\n        this.setGain(EqualizerFilter.F64, value);\n    }\n    public get f64(): number\n    {\n        return this.getGain(EqualizerFilter.F64);\n    }\n\n    /**\n     * Gain at 125 Hz frequencey.\n     * @default 0\n     */\n    public set f125(value: number)\n    {\n        this.setGain(EqualizerFilter.F125, value);\n    }\n    public get f125(): number\n    {\n        return this.getGain(EqualizerFilter.F125);\n    }\n\n    /**\n     * Gain at 250 Hz frequencey.\n     * @default 0\n     */\n    public set f250(value: number)\n    {\n        this.setGain(EqualizerFilter.F250, value);\n    }\n    public get f250(): number\n    {\n        return this.getGain(EqualizerFilter.F250);\n    }\n\n    /**\n     * Gain at 500 Hz frequencey.\n     * @default 0\n     */\n    public set f500(value: number)\n    {\n        this.setGain(EqualizerFilter.F500, value);\n    }\n    public get f500(): number\n    {\n        return this.getGain(EqualizerFilter.F500);\n    }\n\n    /**\n     * Gain at 1 KHz frequencey.\n     * @default 0\n     */\n    public set f1k(value: number)\n    {\n        this.setGain(EqualizerFilter.F1K, value);\n    }\n    public get f1k(): number\n    {\n        return this.getGain(EqualizerFilter.F1K);\n    }\n\n    /**\n     * Gain at 2 KHz frequencey.\n     * @default 0\n     */\n    public set f2k(value: number)\n    {\n        this.setGain(EqualizerFilter.F2K, value);\n    }\n    public get f2k(): number\n    {\n        return this.getGain(EqualizerFilter.F2K);\n    }\n\n    /**\n     * Gain at 4 KHz frequencey.\n     * @default 0\n     */\n    public set f4k(value: number)\n    {\n        this.setGain(EqualizerFilter.F4K, value);\n    }\n    public get f4k(): number\n    {\n        return this.getGain(EqualizerFilter.F4K);\n    }\n\n    /**\n     * Gain at 8 KHz frequencey.\n     * @default 0\n     */\n    public set f8k(value: number)\n    {\n        this.setGain(EqualizerFilter.F8K, value);\n    }\n    public get f8k(): number\n    {\n        return this.getGain(EqualizerFilter.F8K);\n    }\n\n    /**\n     * Gain at 16 KHz frequencey.\n     * @default 0\n     */\n    public set f16k(value: number)\n    {\n        this.setGain(EqualizerFilter.F16K, value);\n    }\n    public get f16k(): number\n    {\n        return this.getGain(EqualizerFilter.F16K);\n    }\n\n    /** Reset all frequency bands to have gain of 0 */\n    public reset(): void\n    {\n        this.bands.forEach((band: BiquadFilterNode) =>\n        {\n            WebAudioUtils.setParamValue(band.gain, 0);\n        });\n    }\n\n    public destroy(): void\n    {\n        this.bands.forEach((band: BiquadFilterNode) =>\n        {\n            band.disconnect();\n        });\n        (this as any).bands = null;\n        (this as any).bandsMap = null;\n    }\n}\n\nexport { EqualizerFilter };\n","import { getInstance } from '../instance';\nimport { Filter } from './Filter';\n\n/**\n * Combine all channels into mono channel.\n *\n * @memberof filters\n */\nclass MonoFilter extends Filter\n{\n    /** Merger node */\n    private _merger: ChannelMergerNode;\n\n    constructor()\n    {\n        let merger: ChannelMergerNode;\n        let splitter: ChannelSplitterNode;\n\n        if (!getInstance().useLegacy)\n        {\n            const { audioContext } = getInstance().context;\n\n            splitter = audioContext.createChannelSplitter();\n            merger = audioContext.createChannelMerger();\n            merger.connect(splitter);\n        }\n        super(merger, splitter);\n        this._merger = merger;\n    }\n\n    public destroy(): void\n    {\n        this._merger?.disconnect();\n        this._merger = null;\n        super.destroy();\n    }\n}\n\nexport { MonoFilter };\n","import { getInstance } from '../instance';\nimport { Filter } from './Filter';\n\n/**\n * Filter for adding reverb. Refactored from\n * https://github.com/web-audio-components/simple-reverb/\n *\n * @memberof filters\n */\nclass ReverbFilter extends Filter\n{\n    private _seconds: number;\n    private _decay: number;\n    private _reverse: boolean;\n\n    /**\n     * @param seconds - Seconds for reverb\n     * @param decay - The decay length\n     * @param reverse - Reverse reverb\n     */\n    constructor(seconds = 3, decay = 2, reverse = false)\n    {\n        super(null);\n        this._seconds = this._clamp(seconds, 1, 50);\n        this._decay = this._clamp(decay, 0, 100);\n        this._reverse = reverse;\n        this._rebuild();\n    }\n\n    /**\n     * Clamp a value\n     * @param value\n     * @param min - Minimum value\n     * @param max - Maximum value\n     * @return Clamped number\n     */\n    private _clamp(value: number, min: number, max: number): number\n    {\n        return Math.min(max, Math.max(min, value));\n    }\n\n    /**\n     * Length of reverb in seconds from 1 to 50\n     * @default 3\n     */\n    get seconds(): number\n    {\n        return this._seconds;\n    }\n    set seconds(seconds: number)\n    {\n        this._seconds = this._clamp(seconds, 1, 50);\n        this._rebuild();\n    }\n\n    /**\n     * Decay value from 0 to 100\n     * @default 2\n     */\n    get decay(): number\n    {\n        return this._decay;\n    }\n    set decay(decay: number)\n    {\n        this._decay = this._clamp(decay, 0, 100);\n        this._rebuild();\n    }\n\n    /**\n     * Reverse value from 0 to 1\n     * @default false\n     */\n    get reverse(): boolean\n    {\n        return this._reverse;\n    }\n    set reverse(reverse: boolean)\n    {\n        this._reverse = reverse;\n        this._rebuild();\n    }\n\n    /**\n     * Utility function for building an impulse response\n     * from the module parameters.\n     */\n    private _rebuild(): void\n    {\n        if (getInstance().useLegacy)\n        {\n            return;\n        }\n        const { audioContext } = getInstance().context;\n        const rate: number = audioContext.sampleRate;\n        const length: number = rate * this._seconds;\n        const impulse: AudioBuffer = audioContext.createBuffer(2, length, rate);\n        const impulseL: Float32Array = impulse.getChannelData(0);\n        const impulseR: Float32Array = impulse.getChannelData(1);\n        let n: number;\n\n        for (let i = 0; i < length; i++)\n        {\n            n = this._reverse ? length - i : i;\n            impulseL[i] = ((Math.random() * 2) - 1) * Math.pow(1 - (n / length), this._decay);\n            impulseR[i] = ((Math.random() * 2) - 1) * Math.pow(1 - (n / length), this._decay);\n        }\n        const convolver = audioContext.createConvolver();\n\n        convolver.buffer = impulse;\n        this.init(convolver);\n    }\n}\n\nexport { ReverbFilter };\n","import { getInstance } from '../instance';\nimport { WebAudioUtils } from '../webaudio/WebAudioUtils';\nimport { Filter } from './Filter';\n\n/**\n * Filter for adding Stereo panning.\n *\n * @memberof filters\n */\nclass StereoFilter extends Filter\n{\n    /** The stereo panning node */\n    private _stereo: StereoPannerNode;\n\n    /** The stereo panning node */\n    private _panner: PannerNode;\n\n    /** The amount of panning, -1 is left, 1 is right, 0 is centered */\n    private _pan: number;\n\n    /** @param pan - The amount of panning, -1 is left, 1 is right, 0 is centered. */\n    constructor(pan = 0)\n    {\n        let stereo: StereoPannerNode;\n        let panner: PannerNode;\n        let destination: AudioNode;\n\n        if (!getInstance().useLegacy)\n        {\n            const { audioContext } = getInstance().context;\n\n            if (audioContext.createStereoPanner)\n            {\n                stereo = audioContext.createStereoPanner();\n                destination = stereo;\n            }\n            else\n            {\n                panner = audioContext.createPanner();\n                panner.panningModel = 'equalpower';\n                destination = panner;\n            }\n        }\n\n        super(destination);\n\n        this._stereo = stereo;\n        this._panner = panner;\n\n        this.pan = pan;\n    }\n\n    /** Set the amount of panning, where -1 is left, 1 is right, and 0 is centered */\n    set pan(value: number)\n    {\n        this._pan = value;\n        if (this._stereo)\n        {\n            WebAudioUtils.setParamValue(this._stereo.pan, value);\n        }\n        else if (this._panner)\n        {\n            this._panner.setPosition(value, 0, 1 - Math.abs(value));\n        }\n    }\n    get pan(): number\n    {\n        return this._pan;\n    }\n\n    public destroy(): void\n    {\n        super.destroy();\n        this._stereo = null;\n        this._panner = null;\n    }\n}\n\nexport { StereoFilter };\n","import { getInstance } from '../instance';\nimport { Filter } from './Filter';\n\n/**\n * Export a MediaStream to be recorded\n *\n * @memberof filters\n */\nclass StreamFilter extends Filter\n{\n    private _stream: MediaStream;\n\n    constructor()\n    {\n        let destination: MediaStreamAudioDestinationNode;\n        let source: MediaStreamAudioSourceNode;\n\n        if (!getInstance().useLegacy)\n        {\n            const { audioContext } = getInstance().context;\n\n            destination = audioContext.createMediaStreamDestination();\n            source = audioContext.createMediaStreamSource(destination.stream);\n        }\n\n        super(destination, source);\n        this._stream = destination?.stream;\n    }\n\n    public get stream(): MediaStream\n    {\n        return this._stream;\n    }\n\n    public destroy(): void\n    {\n        this._stream = null;\n        super.destroy();\n    }\n}\n\nexport { StreamFilter };\n","import { getInstance } from '../instance';\nimport { WebAudioUtils } from '../webaudio/WebAudioUtils';\nimport { Filter } from './Filter';\n\n/**\n * Creates a telephone-sound filter.\n *\n * @memberof filters\n */\nclass TelephoneFilter extends Filter\n{\n    constructor()\n    {\n        let destination: AudioNode;\n        let source: AudioNode;\n\n        if (!getInstance().useLegacy)\n        {\n            const { audioContext } = getInstance().context;\n            const lpf1 = audioContext.createBiquadFilter();\n            const lpf2 = audioContext.createBiquadFilter();\n            const hpf1 = audioContext.createBiquadFilter();\n            const hpf2 = audioContext.createBiquadFilter();\n\n            lpf1.type = 'lowpass';\n            WebAudioUtils.setParamValue(lpf1.frequency, 2000.0);\n\n            lpf2.type = 'lowpass';\n            WebAudioUtils.setParamValue(lpf2.frequency, 2000.0);\n\n            hpf1.type = 'highpass';\n            WebAudioUtils.setParamValue(hpf1.frequency, 500.0);\n\n            hpf2.type = 'highpass';\n            WebAudioUtils.setParamValue(hpf2.frequency, 500.0);\n\n            lpf1.connect(lpf2);\n            lpf2.connect(hpf1);\n            hpf1.connect(hpf2);\n\n            destination = lpf1;\n            source = hpf2;\n        }\n\n        super(destination, source);\n    }\n}\n\nexport { TelephoneFilter };\n","import { EventEmitter } from 'pixi.js';\nimport { Filter } from '../filters/Filter';\nimport { IMediaContext } from '../interfaces/IMediaContext';\n\n/**\n * The fallback version of WebAudioContext which uses `<audio>` instead of WebAudio API.\n * @memberof htmlaudio\n * @extends PIXI.EventEmitter\n */\nclass HTMLAudioContext extends EventEmitter implements IMediaContext\n{\n    /** Current global speed from 0 to 1 */\n    public speed = 1;\n\n    /** Current muted status of the context */\n    public muted = false;\n\n    /** Current volume from 0 to 1  */\n    public volume = 1;\n\n    /** Current paused status */\n    public paused = false;\n\n    /** Internal trigger when volume, mute or speed changes */\n    public refresh(): void\n    {\n        this.emit('refresh');\n    }\n\n    /** Internal trigger paused changes */\n    public refreshPaused(): void\n    {\n        this.emit('refreshPaused');\n    }\n\n    /**\n     * HTML Audio does not support filters, this is non-functional API.\n     */\n    public get filters(): Filter[]\n    {\n        console.warn('HTML Audio does not support filters');\n\n        return null;\n    }\n    public set filters(_filters: Filter[])\n    {\n        console.warn('HTML Audio does not support filters');\n    }\n\n    /**\n     * HTML Audio does not support `audioContext`\n     * @readonly\n     * @type {AudioContext}\n     */\n    public get audioContext(): AudioContext\n    {\n        console.warn('HTML Audio does not support audioContext');\n\n        return null;\n    }\n\n    /**\n     * Toggles the muted state.\n     * @return The current muted state.\n     */\n    public toggleMute(): boolean\n    {\n        this.muted = !this.muted;\n        this.refresh();\n\n        return this.muted;\n    }\n\n    /**\n     * Toggles the paused state.\n     * @return The current paused state.\n     */\n    public togglePause(): boolean\n    {\n        this.paused = !this.paused;\n        this.refreshPaused();\n\n        return this.paused;\n    }\n\n    /** Destroy and don't use after this */\n    public destroy(): void\n    {\n        this.removeAllListeners();\n    }\n}\n\nexport { HTMLAudioContext };\n","import { EventEmitter, Ticker } from 'pixi.js';\nimport { Filter } from '../filters/Filter';\nimport { IMediaInstance } from '../interfaces/IMediaInstance';\nimport { PlayOptions } from '../Sound';\nimport { HTMLAudioMedia } from './HTMLAudioMedia';\n\nlet id = 0;\n\n/**\n * Instance which wraps the `<audio>` element playback.\n * @memberof htmlaudio\n * @extends PIXI.EventEmitter\n */\nclass HTMLAudioInstance extends EventEmitter implements IMediaInstance\n{\n    /** Extra padding, in seconds, to deal with low-latecy of HTMLAudio. */\n    public static readonly PADDING: number = 0.1;\n\n    /** The current unique ID for this instance. */\n    public readonly id: number;\n\n    /** The instance of the Audio element. */\n    private _source: HTMLAudioElement;\n\n    /** The instance of the Audio media element. */\n    private _media: HTMLAudioMedia;\n\n    /** Playback rate, where 1 is 100%. */\n    private _end: number;\n\n    /** Current instance paused state. */\n    private _paused: boolean;\n\n    /** Current instance muted state. */\n    private _muted: boolean;\n\n    /** Current actual paused state. */\n    private _pausedReal: boolean;\n\n    /** Total length of the audio. */\n    private _duration: number;\n\n    /** Playback rate, where 1 is 100%. */\n    private _start: number;\n\n    /** `true` if the audio is actually playing. */\n    private _playing: boolean;\n\n    /** Volume for the instance. */\n    private _volume: number;\n\n    /** Speed for the instance. */\n    private _speed: number;\n\n    /** `true` for looping the playback */\n    private _loop: boolean;\n\n    /** @param parent - Parent element */\n    constructor(parent: HTMLAudioMedia)\n    {\n        super();\n\n        this.id = id++;\n\n        this.init(parent);\n    }\n\n    /**\n     * Set a property by name, this makes it easy to chain values\n     * @param name - Name of the property to set\n     * @param value - Value to set property to\n     */\n    public set(name: 'speed' | 'volume' | 'muted' | 'loop' | 'paused', value: number | boolean): this\n    {\n        if (this[name] === undefined)\n        {\n            throw new Error(`Property with name ${name} does not exist.`);\n        }\n        else\n        {\n            switch (name)\n            {\n                case 'speed': this.speed = value as number; break;\n                case 'volume': this.volume = value as number; break;\n                case 'paused': this.paused = value as boolean; break;\n                case 'loop': this.loop = value as boolean; break;\n                case 'muted': this.muted = value as boolean; break;\n            }\n        }\n\n        return this;\n    }\n\n    /** The current playback progress from 0 to 1. */\n    public get progress(): number\n    {\n        const { currentTime } = this._source;\n\n        return currentTime / this._duration;\n    }\n\n    /** Pauses the sound. */\n    public get paused(): boolean\n    {\n        return this._paused;\n    }\n    public set paused(paused: boolean)\n    {\n        this._paused = paused;\n        this.refreshPaused();\n    }\n\n    /**\n     * Reference: http://stackoverflow.com/a/40370077\n     * @private\n     */\n    private _onPlay(): void\n    {\n        this._playing = true;\n    }\n\n    /**\n     * Reference: http://stackoverflow.com/a/40370077\n     * @private\n     */\n    private _onPause(): void\n    {\n        this._playing = false;\n    }\n\n    /**\n     * Initialize the instance.\n     * @param {htmlaudio.HTMLAudioMedia} media - Same as constructor\n     */\n    public init(media: HTMLAudioMedia): void\n    {\n        this._playing = false;\n        this._duration = media.source.duration;\n        const source = this._source = media.source.cloneNode(false) as HTMLAudioElement;\n\n        source.src = media.parent.url;\n        source.onplay = this._onPlay.bind(this);\n        source.onpause = this._onPause.bind(this);\n        media.context.on('refresh', this.refresh, this);\n        media.context.on('refreshPaused', this.refreshPaused, this);\n        this._media = media;\n    }\n\n    /**\n     * Stop the sound playing\n     * @private\n     */\n    private _internalStop(): void\n    {\n        if (this._source && this._playing)\n        {\n            this._source.onended = null;\n            this._source.pause();\n        }\n    }\n\n    /** Stop the sound playing */\n    public stop(): void\n    {\n        this._internalStop();\n\n        if (this._source)\n        {\n            this.emit('stop');\n        }\n    }\n\n    /** Set the instance speed from 0 to 1 */\n    public get speed(): number\n    {\n        return this._speed;\n    }\n    public set speed(speed: number)\n    {\n        this._speed = speed;\n        this.refresh();\n    }\n\n    /** Get the set the volume for this instance from 0 to 1 */\n    public get volume(): number\n    {\n        return this._volume;\n    }\n    public set volume(volume: number)\n    {\n        this._volume = volume;\n        this.refresh();\n    }\n\n    /** If the sound instance should loop playback */\n    public get loop(): boolean\n    {\n        return this._loop;\n    }\n    public set loop(loop: boolean)\n    {\n        this._loop = loop;\n        this.refresh();\n    }\n\n    /** `true` if the sound is muted */\n    public get muted(): boolean\n    {\n        return this._muted;\n    }\n    public set muted(muted: boolean)\n    {\n        this._muted = muted;\n        this.refresh();\n    }\n\n    /**\n     * HTML Audio does not support filters, this is non-functional API.\n     */\n    public get filters(): Filter[]\n    {\n        console.warn('HTML Audio does not support filters');\n\n        return null;\n    }\n    public set filters(_filters: Filter[])\n    {\n        console.warn('HTML Audio does not support filters');\n    }\n\n    /** Call whenever the loop, speed or volume changes */\n    public refresh(): void\n    {\n        const global = this._media.context;\n        const sound = this._media.parent;\n\n        // Update the looping\n        this._source.loop = this._loop || sound.loop;\n\n        // Update the volume\n        const globalVolume = global.volume * (global.muted ? 0 : 1);\n        const soundVolume = sound.volume * (sound.muted ? 0 : 1);\n        const instanceVolume = this._volume * (this._muted ? 0 : 1);\n\n        this._source.volume = instanceVolume * globalVolume * soundVolume;\n\n        // Update the speed\n        this._source.playbackRate = this._speed * global.speed * sound.speed;\n    }\n\n    /** Handle changes in paused state, either globally or sound or instance */\n    public refreshPaused(): void\n    {\n        const global = this._media.context;\n        const sound = this._media.parent;\n\n        // Handle the paused state\n        const pausedReal = this._paused || sound.paused || global.paused;\n\n        if (pausedReal !== this._pausedReal)\n        {\n            this._pausedReal = pausedReal;\n\n            if (pausedReal)\n            {\n                this._internalStop();\n\n                /**\n                 * The sound is paused.\n                 * @event paused\n                 */\n                this.emit('paused');\n            }\n            else\n            {\n                /**\n                 * The sound is unpaused.\n                 * @event resumed\n                 */\n                this.emit('resumed');\n\n                // resume the playing with offset\n                this.play({\n                    start: this._source.currentTime,\n                    end: this._end,\n                    volume: this._volume,\n                    speed: this._speed,\n                    loop: this._loop,\n                });\n            }\n\n            /**\n             * The sound is paused or unpaused.\n             * @event pause\n             * @property {boolean} paused - If the instance was paused or not.\n             */\n            this.emit('pause', pausedReal);\n        }\n    }\n\n    /** Start playing the sound/ */\n    public play(options: PlayOptions): void\n    {\n        const { start, end, speed, loop, volume, muted } = options;\n\n        if (end)\n        {\n            // eslint-disable-next-line no-console\n            console.assert(end > start, 'End time is before start time');\n        }\n\n        this._speed = speed;\n        this._volume = volume;\n        this._loop = !!loop;\n        this._muted = muted;\n        this.refresh();\n\n        // WebAudio doesn't support looping when a duration is set\n        // we'll set this just for the heck of it\n        if (this.loop && end !== null)\n        {\n            console.warn('Looping not support when specifying an \"end\" time');\n            this.loop = false;\n        }\n\n        this._start = start;\n        this._end = end || this._duration;\n\n        // Lets expand the start and end a little\n        // to deal with the low-latecy of playing audio this way\n        // this is a little fudge-factor\n        this._start = Math.max(0, this._start - HTMLAudioInstance.PADDING);\n        this._end = Math.min(this._end + HTMLAudioInstance.PADDING, this._duration);\n\n        this._source.onloadedmetadata = () =>\n        {\n            if (this._source)\n            {\n                this._source.currentTime = start;\n                this._source.onloadedmetadata = null;\n                this.emit('progress', start / this._duration, this._duration);\n                Ticker.shared.add(this._onUpdate, this);\n            }\n        };\n        this._source.onended = this._onComplete.bind(this);\n        this._source.play();\n\n        /**\n         * The sound is started.\n         * @event start\n         */\n        this.emit('start');\n    }\n\n    /**\n     * Handle time update on sound.\n     * @private\n     */\n    private _onUpdate(): void\n    {\n        this.emit('progress', this.progress, this._duration);\n        if (this._source.currentTime >= this._end && !this._source.loop)\n        {\n            this._onComplete();\n        }\n    }\n\n    /**\n     * Callback when completed.\n     * @private\n     */\n    private _onComplete(): void\n    {\n        Ticker.shared.remove(this._onUpdate, this);\n        this._internalStop();\n        this.emit('progress', 1, this._duration);\n        /**\n         * The sound ends, don't use after this\n         * @event end\n         */\n        this.emit('end', this);\n    }\n\n    /** Don't use after this. */\n    public destroy(): void\n    {\n        Ticker.shared.remove(this._onUpdate, this);\n        this.removeAllListeners();\n\n        const source = this._source;\n\n        if (source)\n        {\n            // Remove the listeners\n            source.onended = null;\n            source.onplay = null;\n            source.onpause = null;\n\n            this._internalStop();\n        }\n\n        this._source = null;\n        this._speed = 1;\n        this._volume = 1;\n        this._loop = false;\n        this._end = null;\n        this._start = 0;\n        this._duration = 0;\n        this._playing = false;\n        this._pausedReal = false;\n        this._paused = false;\n        this._muted = false;\n\n        if (this._media)\n        {\n            this._media.context.off('refresh', this.refresh, this);\n            this._media.context.off('refreshPaused', this.refreshPaused, this);\n            this._media = null;\n        }\n    }\n\n    /**\n     * To string method for instance.\n     * @return The string representation of instance.\n     */\n    public toString(): string\n    {\n        return `[HTMLAudioInstance id=${this.id}]`;\n    }\n}\n\nexport { HTMLAudioInstance };\n","import { EventEmitter } from 'pixi.js';\nimport { Filter } from '../filters/Filter';\nimport { IMedia } from '../interfaces/IMedia';\nimport { LoadedCallback, Sound } from '../Sound';\nimport { HTMLAudioContext } from './HTMLAudioContext';\nimport { HTMLAudioInstance } from './HTMLAudioInstance';\n\n/**\n * The fallback version of Sound which uses `<audio>` instead of WebAudio API.\n * @memberof htmlaudio\n * @extends PIXI.EventEmitter\n */\nclass HTMLAudioMedia extends EventEmitter implements IMedia\n{\n    public parent: Sound;\n    private _source: HTMLAudioElement;\n\n    public init(parent: Sound): void\n    {\n        this.parent = parent;\n        this._source = parent.options.source as HTMLAudioElement || new Audio();\n        if (parent.url)\n        {\n            this._source.src = parent.url;\n        }\n    }\n\n    // Implement create\n    public create(): HTMLAudioInstance\n    {\n        return new HTMLAudioInstance(this);\n    }\n\n    /**\n     * If the audio media is playable (ready).\n     * @readonly\n     */\n    public get isPlayable(): boolean\n    {\n        return !!this._source && this._source.readyState === 4;\n    }\n\n    /**\n     * THe duration of the media in seconds.\n     * @readonly\n     */\n    public get duration(): number\n    {\n        return this._source.duration;\n    }\n\n    /**\n     * Reference to the context.\n     * @readonly\n     */\n    public get context(): HTMLAudioContext\n    {\n        return this.parent.context as HTMLAudioContext;\n    }\n\n    /** The collection of filters, does not apply to HTML Audio. */\n    public get filters(): Filter[]\n    {\n        return null;\n    }\n    public set filters(_filters: Filter[])\n    {\n        console.warn('HTML Audio does not support filters');\n    }\n\n    // Override the destroy\n    public destroy(): void\n    {\n        this.removeAllListeners();\n\n        this.parent = null;\n\n        if (this._source)\n        {\n            this._source.src = '';\n            this._source.load();\n            this._source = null;\n        }\n    }\n\n    /**\n     * Get the audio source element.\n     * @type {HTMLAudioElement}\n     * @readonly\n     */\n    public get source(): HTMLAudioElement\n    {\n        return this._source;\n    }\n\n    // Implement the method to being preloading\n    public load(callback?: LoadedCallback): void\n    {\n        const source = this._source;\n        const sound = this.parent;\n\n        // See if the source is already loaded\n        if (source.readyState === 4)\n        {\n            sound.isLoaded = true;\n            const instance = sound.autoPlayStart();\n\n            if (callback)\n            {\n                setTimeout(() =>\n                {\n                    callback(null, sound, instance);\n                }, 0);\n            }\n\n            return;\n        }\n\n        // If there's no source, we cannot load\n        if (!sound.url)\n        {\n            callback(new Error('sound.url or sound.source must be set'));\n\n            return;\n        }\n\n        // Set the source\n        source.src = sound.url;\n\n        const onLoad = () =>\n        {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            removeListeners();\n            sound.isLoaded = true;\n            const instance = sound.autoPlayStart();\n\n            if (callback)\n            {\n                callback(null, sound, instance);\n            }\n        };\n\n        const onAbort = () =>\n        {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            removeListeners();\n            if (callback)\n            {\n                callback(new Error('Sound loading has been aborted'));\n            }\n        };\n\n        const onError = () =>\n        {\n            // eslint-disable-next-line @typescript-eslint/no-use-before-define\n            removeListeners();\n            const message = `Failed to load audio element (code: ${source.error.code})`;\n\n            if (callback)\n            {\n                callback(new Error(message));\n            }\n            else\n            {\n                console.error(message);\n            }\n        };\n\n        // Remove all event listeners\n        const removeListeners = () =>\n        {\n            // Listen for callback\n            source.removeEventListener('canplaythrough', onLoad);\n            source.removeEventListener('load', onLoad);\n            source.removeEventListener('abort', onAbort);\n            source.removeEventListener('error', onError);\n        };\n\n        // Listen for callback\n        source.addEventListener('canplaythrough', onLoad, false);\n        source.addEventListener('load', onLoad, false);\n        source.addEventListener('abort', onAbort, false);\n        source.addEventListener('error', onError, false);\n\n        // Begin the loading\n        source.load();\n    }\n}\n\nexport { HTMLAudioMedia };\n","import { IMediaInstance } from './interfaces';\nimport { CompleteCallback, Sound } from './Sound';\n\n/** Data for adding new sound sprites. */\ninterface SoundSpriteData\n{\n    /** The start time in seconds. */\n    start: number;\n    /** The end time in seconds. */\n    end: number;\n    /** The optional speed, if not speed, uses the default speed of the parent. */\n    speed?: number;\n}\n\n// Collection of sound sprites\ntype SoundSprites = Record<string, SoundSprite>;\n\n/**\n * Object that represents a single Sound's sprite. To add sound sprites\n * use the {@link Sound#addSprites} method.\n * @example\n * import { sound } from '@pixi/sound';\n * sound.add('alias', {\n *   url: 'path/to/file.ogg',\n *   sprites: {\n *     blast: { start: 0, end: 0.2 },\n *     boom: { start: 0.3, end: 0.5 },\n *   },\n *   loaded() {\n *     sound.play('alias', 'blast');\n *   }\n * );\n *\n */\nclass SoundSprite\n{\n    /**\n     * The reference sound\n     * @readonly\n     */\n    public parent: Sound;\n\n    /**\n     * The starting location in seconds.\n     * @readonly\n     */\n    public start: number;\n\n    /**\n     * The ending location in seconds\n     * @readonly\n     */\n    public end: number;\n\n    /**\n     * The speed override where 1 is 100% speed playback.\n     * @readonly\n     */\n    public speed: number;\n\n    /**\n     * The duration of the sound in seconds.\n     * @readonly\n     */\n    public duration: number;\n\n    /**\n     * Whether to loop the sound sprite.\n     * @readonly\n     */\n    public loop: boolean;\n\n    /**\n     * @param parent - The parent sound\n     * @param options - Data associated with object.\n     */\n    constructor(parent: Sound, options: SoundSpriteData)\n    {\n        this.parent = parent;\n        Object.assign(this, options);\n        this.duration = this.end - this.start;\n\n        // eslint-disable-next-line no-console\n        console.assert(this.duration > 0, 'End time must be after start time');\n    }\n\n    /**\n     * Play the sound sprite.\n     * @param {Function} [complete] - Function call when complete\n     * @return Sound instance being played.\n     */\n    public play(complete?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>\n    {\n        return this.parent.play({\n            complete,\n            speed: this.speed || this.parent.speed,\n            end: this.end,\n            start: this.start,\n            loop: this.loop\n        });\n    }\n\n    /** Destroy and don't use after this */\n    public destroy(): void\n    {\n        this.parent = null;\n    }\n}\n\nexport type { SoundSpriteData, SoundSprites };\nexport { SoundSprite };\n","type ExtensionMap = Record<string, boolean>;\n\n/**\n * The list of extensions that can be played. This is the preferred order of playback.\n * If you want to priority the order of playback, you can use this array to do so.\n * @readonly\n * @memberof utils\n */\nconst extensions: string[] = [\n    'ogg',\n    'oga',\n    'opus',\n    'm4a',\n    'mp3',\n    'mpeg',\n    'wav',\n    'aiff',\n    'wma',\n    'mid',\n    'caf',\n];\n\nconst mimes: string[] = [\n    'audio/mpeg',\n    'audio/ogg',\n];\n\n/**\n * The list of browser supported audio formats.\n * @readonly\n * @memberof utils\n * @property {boolean} mp3 - `true` if file-type is supported\n * @property {boolean} ogg - `true` if file-type is supported\n * @property {boolean} oga - `true` if file-type is supported\n * @property {boolean} opus - `true` if file-type is supported\n * @property {boolean} mpeg - `true` if file-type is supported\n * @property {boolean} wav - `true` if file-type is supported\n * @property {boolean} aiff - `true` if file-type is supported\n * @property {boolean} wma - `true` if file-type is supported\n * @property {boolean} mid - `true` if file-type is supported\n * @property {boolean} caf - `true` if file-type is supported. Note that for this we check if the\n *                             'opus' codec is supported inside the caf container.\n */\nconst supported: ExtensionMap = {};\n\n/**\n * Function to validate file type formats. This is called when the library initializes, but can\n * be called again if you need to recognize a format not listed in `utils.extensions` at\n * initialization.\n * @memberof utils\n * @param typeOverrides - - Dictionary of type overrides (inputs for\n *                                 AudioElement.canPlayType()), keyed by extension from the\n *                                 utils.extensions array.\n */\nfunction validateFormats(typeOverrides?: Record<string, string>): void\n{\n    const overrides: Record<string, string> = {\n        m4a: 'audio/mp4',\n        oga: 'audio/ogg',\n        opus: 'audio/ogg; codecs=\"opus\"',\n        caf: 'audio/x-caf; codecs=\"opus\"', ...(typeOverrides || {})\n    };\n    const audio = document.createElement('audio');\n    const formats: ExtensionMap = {};\n    const no = /^no$/;\n\n    extensions.forEach((ext) =>\n    {\n        const canByExt = audio.canPlayType(`audio/${ext}`).replace(no, '');\n        const canByType = overrides[ext] ? audio.canPlayType(overrides[ext]).replace(no, '') : '';\n\n        formats[ext] = !!canByExt || !!canByType;\n    });\n    Object.assign(supported, formats);\n}\n\n// initialize supported\nvalidateFormats();\n\nexport {\n    extensions,\n    mimes,\n    supported,\n    validateFormats,\n};\n","import { EventEmitter, Ticker } from 'pixi.js';\nimport { Filter } from '../filters/Filter';\nimport { IMediaInstance } from '../interfaces';\nimport { PlayOptions } from '../Sound';\nimport { WebAudioMedia } from './WebAudioMedia';\nimport { WebAudioUtils } from './WebAudioUtils';\n\nlet id = 0;\n\n/**\n * A single play instance that handles the AudioBufferSourceNode.\n * @memberof webaudio\n * @extends PIXI.EventEmitter\n */\nclass WebAudioInstance extends EventEmitter implements IMediaInstance\n{\n    /**\n     * The current unique ID for this instance.\n     * @readonly\n     */\n    public readonly id: number;\n\n    /** The source Sound. */\n    private _media: WebAudioMedia;\n\n    /** true if paused. */\n    private _paused: boolean;\n\n    /** true if muted. */\n    private _muted: boolean;\n\n    /** true if paused. */\n    private _pausedReal: boolean;\n\n    /** The instance volume */\n    private _volume: number;\n\n    /** Last update frame number. */\n    private _lastUpdate: number;\n\n    /** The total number of seconds elapsed in playback. */\n    private _elapsed: number;\n\n    /** Playback rate, where 1 is 100%. */\n    private _speed: number;\n\n    /** Playback rate, where 1 is 100%. */\n    private _end: number;\n\n    /** `true` if should be looping. */\n    private _loop: boolean;\n\n    /** Gain node for controlling volume of instance */\n    private _gain: GainNode;\n\n    /** Length of the sound in seconds. */\n    private _duration: number;\n\n    /** The progress of the sound from 0 to 1. */\n    private _progress: number;\n\n    /** Audio buffer source clone from Sound object. */\n    private _source: AudioBufferSourceNode;\n\n    /** The filters */\n    private _filters: Filter[];\n\n    constructor(media: WebAudioMedia)\n    {\n        super();\n\n        this.id = id++;\n        this._media = null;\n        this._paused = false;\n        this._muted = false;\n        this._elapsed = 0;\n\n        // Initialize\n        this.init(media);\n    }\n\n    /**\n     * Set a property by name, this makes it easy to chain values\n     * @param name - Name of the property to set.\n     * @param value - Value to set property to.\n     */\n    public set(name: 'speed' | 'volume' | 'muted' | 'loop' | 'paused', value: number | boolean): this\n    {\n        if (this[name] === undefined)\n        {\n            throw new Error(`Property with name ${name} does not exist.`);\n        }\n        else\n        {\n            switch (name)\n            {\n                case 'speed': this.speed = value as number; break;\n                case 'volume': this.volume = value as number; break;\n                case 'muted': this.muted = value as boolean; break;\n                case 'loop': this.loop = value as boolean; break;\n                case 'paused': this.paused = value as boolean; break;\n            }\n        }\n\n        return this;\n    }\n\n    /** Stops the instance, don't use after this. */\n    public stop(): void\n    {\n        if (this._source)\n        {\n            this._internalStop();\n            this.emit('stop');\n        }\n    }\n\n    /** Set the instance speed from 0 to 1 */\n    public get speed(): number\n    {\n        return this._speed;\n    }\n    public set speed(speed: number)\n    {\n        this._speed = speed;\n        this.refresh();\n        this._update(true); // update progress\n    }\n\n    /** Get the set the volume for this instance from 0 to 1 */\n    public get volume(): number\n    {\n        return this._volume;\n    }\n    public set volume(volume: number)\n    {\n        this._volume = volume;\n        this.refresh();\n    }\n\n    /** `true` if the sound is muted */\n    public get muted(): boolean\n    {\n        return this._muted;\n    }\n    public set muted(muted: boolean)\n    {\n        this._muted = muted;\n        this.refresh();\n    }\n\n    /** If the sound instance should loop playback */\n    public get loop(): boolean\n    {\n        return this._loop;\n    }\n    public set loop(loop: boolean)\n    {\n        this._loop = loop;\n        this.refresh();\n    }\n\n    /** The collection of filters. */\n    public get filters(): Filter[]\n    {\n        return this._filters;\n    }\n    public set filters(filters: Filter[])\n    {\n        if (this._filters)\n        {\n            this._filters?.filter((filter) => filter).forEach((filter) => filter.disconnect());\n            this._filters = null;\n            // Reconnect direct path\n            this._source.connect(this._gain);\n        }\n        this._filters = filters?.length ? filters.slice(0) : null;\n        this.refresh();\n    }\n\n    /** Refresh loop, volume and speed based on changes to parent */\n    public refresh(): void\n    {\n        // Sound could be paused\n        if (!this._source)\n        {\n            return;\n        }\n        const global = this._media.context;\n        const sound = this._media.parent;\n\n        // Updating looping\n        this._source.loop = this._loop || sound.loop;\n\n        // Update the volume\n        const globalVolume = global.volume * (global.muted ? 0 : 1);\n        const soundVolume = sound.volume * (sound.muted ? 0 : 1);\n        const instanceVolume = this._volume * (this._muted ? 0 : 1);\n\n        WebAudioUtils.setParamValue(this._gain.gain, instanceVolume * soundVolume * globalVolume);\n\n        // Update the speed\n        WebAudioUtils.setParamValue(this._source.playbackRate, this._speed * sound.speed * global.speed);\n\n        this.applyFilters();\n    }\n\n    /** Connect filters nodes to audio context */\n    private applyFilters(): void\n    {\n        if (this._filters?.length)\n        {\n            // Disconnect direct path before inserting filters\n            this._source.disconnect();\n\n            // Connect each filter\n            let source: { connect: (node: AudioNode) => void } = this._source;\n\n            this._filters.forEach((filter: Filter) =>\n            {\n                source.connect(filter.destination);\n                source = filter;\n            });\n            source.connect(this._gain);\n        }\n    }\n\n    /** Handle changes in paused state, either globally or sound or instance */\n    public refreshPaused(): void\n    {\n        const global = this._media.context;\n        const sound = this._media.parent;\n\n        // Consider global and sound paused\n        const pausedReal = this._paused || sound.paused || global.paused;\n\n        if (pausedReal !== this._pausedReal)\n        {\n            this._pausedReal = pausedReal;\n\n            if (pausedReal)\n            {\n                // pause the sounds\n                this._internalStop();\n\n                /**\n                 * The sound is paused.\n                 * @event paused\n                 */\n                this.emit('paused');\n            }\n            else\n            {\n                /**\n                 * The sound is unpaused.\n                 * @event resumed\n                 */\n                this.emit('resumed');\n\n                // resume the playing with offset\n                this.play({\n                    start: this._elapsed % this._duration,\n                    end: this._end,\n                    speed: this._speed,\n                    loop: this._loop,\n                    volume: this._volume,\n                });\n            }\n\n            /**\n             * The sound is paused or unpaused.\n             * @event pause\n             * @property {boolean} paused - If the instance was paused or not.\n             */\n            this.emit('pause', pausedReal);\n        }\n    }\n\n    /**\n     * Plays the sound.\n     * @param options - Play options.\n     */\n    public play(options: PlayOptions): void\n    {\n        const { start, end, speed, loop, volume, muted, filters } = options;\n\n        if (end)\n        {\n            // eslint-disable-next-line no-console\n            console.assert(end > start, 'End time is before start time');\n        }\n        this._paused = false;\n        const { source, gain } = this._media.nodes.cloneBufferSource();\n\n        this._source = source;\n        this._gain = gain;\n        this._speed = speed;\n        this._volume = volume;\n        this._loop = !!loop;\n        this._muted = muted;\n        this._filters = filters;\n        this.refresh();\n\n        const duration: number = this._source.buffer.duration;\n\n        this._duration = duration;\n        this._end = end;\n        this._lastUpdate = this._now();\n        this._elapsed = start;\n        this._source.onended = this._onComplete.bind(this);\n\n        if (this._loop)\n        {\n            this._source.loopEnd = end;\n            this._source.loopStart = start;\n            this._source.start(0, start);\n        }\n        else if (end)\n        {\n            this._source.start(0, start, end - start);\n        }\n        else\n        {\n            this._source.start(0, start);\n        }\n\n        /**\n         * The sound is started.\n         * @event start\n         */\n        this.emit('start');\n\n        // Do an update for the initial progress\n        this._update(true);\n\n        // Start handling internal ticks\n        this.enableTicker(true);\n    }\n\n    /** Start the update progress. */\n    private enableTicker(enabled: boolean): void\n    {\n        Ticker.shared.remove(this._updateListener, this);\n        if (enabled)\n        {\n            Ticker.shared.add(this._updateListener, this);\n        }\n    }\n\n    /** The current playback progress from 0 to 1. */\n    public get progress(): number\n    {\n        return this._progress;\n    }\n\n    /** Pauses the sound. */\n    public get paused(): boolean\n    {\n        return this._paused;\n    }\n\n    public set paused(paused: boolean)\n    {\n        this._paused = paused;\n        this.refreshPaused();\n    }\n\n    /** Don't use after this. */\n    public destroy(): void\n    {\n        this.removeAllListeners();\n        this._internalStop();\n        if (this._gain)\n        {\n            this._gain.disconnect();\n            this._gain = null;\n        }\n        if (this._media)\n        {\n            this._media.context.events.off('refresh', this.refresh, this);\n            this._media.context.events.off('refreshPaused', this.refreshPaused, this);\n            this._media = null;\n        }\n        this._filters?.forEach((filter) => filter.disconnect());\n        this._filters = null;\n        this._end = null;\n        this._speed = 1;\n        this._volume = 1;\n        this._loop = false;\n        this._elapsed = 0;\n        this._duration = 0;\n        this._paused = false;\n        this._muted = false;\n        this._pausedReal = false;\n    }\n\n    /**\n     * To string method for instance.\n     * @return The string representation of instance.\n     */\n    public toString(): string\n    {\n        return `[WebAudioInstance id=${this.id}]`;\n    }\n\n    /**\n     * Get the current time in seconds.\n     * @return Seconds since start of context\n     */\n    private _now(): number\n    {\n        return this._media.context.audioContext.currentTime;\n    }\n\n    /** Callback for update listener */\n    private _updateListener()\n    {\n        this._update();\n    }\n\n    /** Internal update the progress. */\n    private _update(force = false): void\n    {\n        if (this._source)\n        {\n            const now: number = this._now();\n            const delta: number = now - this._lastUpdate;\n\n            if (delta > 0 || force)\n            {\n                const speed: number = this._source.playbackRate.value;\n\n                this._elapsed += delta * speed;\n                this._lastUpdate = now;\n                const duration: number = this._duration;\n                let progress: number;\n\n                if (this._source.loopStart)\n                {\n                    const soundLength = this._source.loopEnd - this._source.loopStart;\n\n                    progress = (this._source.loopStart + (this._elapsed % soundLength)) / duration;\n                }\n                else\n                {\n                    progress = (this._elapsed % duration) / duration;\n                }\n\n                // Update the progress\n                this._progress = progress;\n\n                /**\n                 * The sound progress is updated.\n                 * @event progress\n                 * @property {number} progress - Amount progressed from 0 to 1\n                 * @property {number} duration - The total playback in seconds\n                 */\n                this.emit('progress', this._progress, duration);\n            }\n        }\n    }\n\n    /** Initializes the instance. */\n    public init(media: WebAudioMedia): void\n    {\n        this._media = media;\n        media.context.events.on('refresh', this.refresh, this);\n        media.context.events.on('refreshPaused', this.refreshPaused, this);\n    }\n\n    /** Stops the instance. */\n    private _internalStop(): void\n    {\n        if (this._source)\n        {\n            this.enableTicker(false);\n            this._source.onended = null;\n            this._source.stop(0); // param needed for iOS 8 bug\n            this._source.disconnect();\n            try\n            {\n                this._source.buffer = null;\n            }\n            catch (err)\n            {\n                // try/catch workaround for bug in older Chrome versions\n                console.warn('Failed to set AudioBufferSourceNode.buffer to null:', err);\n            }\n            this._source = null;\n        }\n    }\n\n    /** Callback when completed. */\n    private _onComplete(): void\n    {\n        if (this._source)\n        {\n            this.enableTicker(false);\n            this._source.onended = null;\n            this._source.disconnect();\n            try\n            {\n                this._source.buffer = null;\n            }\n            catch (err)\n            {\n                // try/catch workaround for bug in older Chrome versions\n                console.warn('Failed to set AudioBufferSourceNode.buffer to null:', err);\n            }\n        }\n        this._source = null;\n        this._progress = 1;\n        this.emit('progress', 1, this._duration);\n        /**\n         * The sound ends, don't use after this\n         * @event end\n         */\n        this.emit('end', this);\n    }\n}\n\nexport { WebAudioInstance };\n","import { Filter } from './filters/Filter';\n\n/**\n * Abstract class which SoundNodes and SoundContext\n * both extend. This provides the functionality for adding\n * dynamic filters.\n */\nclass Filterable\n{\n    /** Get the gain node */\n    private _input: AudioNode;\n\n    /** The destination output audio node */\n    private _output: AudioNode;\n\n    /** Collection of filters. */\n    private _filters: Filter[];\n\n    /**\n     * @param input - The source audio node\n     * @param output - The output audio node\n     */\n    constructor(input: AudioNode, output: AudioNode)\n    {\n        this._output = output;\n        this._input = input;\n    }\n\n    /** The destination output audio node */\n    get destination(): AudioNode\n    {\n        return this._input;\n    }\n\n    /** The collection of filters. */\n    get filters(): Filter[]\n    {\n        return this._filters;\n    }\n    set filters(filters: Filter[])\n    {\n        if (this._filters)\n        {\n            this._filters.forEach((filter: Filter) =>\n            {\n                if (filter)\n                {\n                    filter.disconnect();\n                }\n            });\n            this._filters = null;\n            // Reconnect direct path\n            this._input.connect(this._output);\n        }\n\n        if (filters && filters.length)\n        {\n            this._filters = filters.slice(0);\n\n            // Disconnect direct path before inserting filters\n            this._input.disconnect();\n\n            // Connect each filter\n            let prevFilter: Filter = null;\n\n            filters.forEach((filter: Filter) =>\n            {\n                if (prevFilter === null)\n                {\n                    // first filter is the destination\n                    // for the analyser\n                    this._input.connect(filter.destination);\n                }\n                else\n                {\n                    prevFilter.connect(filter.destination);\n                }\n                prevFilter = filter;\n            });\n            prevFilter.connect(this._output);\n        }\n    }\n\n    /** Cleans up. */\n    public destroy(): void\n    {\n        this.filters = null;\n        this._input = null;\n        this._output = null;\n    }\n}\n\nexport { Filterable };\n","import { Filterable } from '../Filterable';\nimport { WebAudioContext } from './WebAudioContext';\nimport { WebAudioUtils } from './WebAudioUtils';\n\n/** Output for cloning source node. */\ninterface SourceClone\n{\n    /** Cloned audio buffer source */\n    source: AudioBufferSourceNode;\n    /** Independent volume control */\n    gain: GainNode;\n}\n\n/**\n * @memberof webaudio\n */\nclass WebAudioNodes extends Filterable\n{\n    /**\n     * The buffer size for script processor, default is `0` which auto-detects. If you plan to use\n     * script node on iOS, you'll need to provide a non-zero amount.\n     * @default 0\n     */\n    public static BUFFER_SIZE = 0;\n\n    /**\n     * Get the buffer source node\n     * @readonly\n     */\n    public bufferSource: AudioBufferSourceNode;\n\n    /**\n     * Get the gain node\n     * @readonly\n     */\n    public gain: GainNode;\n\n    /**\n     * Get the analyser node\n     * @readonly\n     */\n    public analyser: AnalyserNode;\n\n    /**\n     * Reference to the SoundContext\n     * @readonly\n     */\n    public context: WebAudioContext;\n\n    /** Private reference to the script processor node. */\n    private _script: ScriptProcessorNode;\n\n    /**\n     * @param context - The audio context.\n     */\n    constructor(context: WebAudioContext)\n    {\n        const audioContext: AudioContext = context.audioContext;\n\n        const bufferSource: AudioBufferSourceNode = audioContext.createBufferSource();\n        const gain: GainNode = audioContext.createGain();\n        const analyser: AnalyserNode = audioContext.createAnalyser();\n\n        bufferSource.connect(analyser);\n        analyser.connect(gain);\n        gain.connect(context.destination);\n\n        super(analyser, gain);\n\n        this.context = context;\n        this.bufferSource = bufferSource;\n        this.gain = gain;\n        this.analyser = analyser;\n    }\n\n    /**\n     * Get the script processor node.\n     * @readonly\n     */\n    public get script(): ScriptProcessorNode\n    {\n        if (!this._script)\n        {\n            this._script = this.context.audioContext.createScriptProcessor(WebAudioNodes.BUFFER_SIZE);\n            this._script.connect(this.context.destination);\n        }\n\n        return this._script;\n    }\n\n    /** Cleans up. */\n    public destroy(): void\n    {\n        super.destroy();\n\n        this.bufferSource.disconnect();\n        if (this._script)\n        {\n            this._script.disconnect();\n        }\n        this.gain.disconnect();\n        this.analyser.disconnect();\n\n        this.bufferSource = null;\n        this._script = null;\n        this.gain = null;\n        this.analyser = null;\n\n        this.context = null;\n    }\n\n    /**\n     * Clones the bufferSource. Used just before playing a sound.\n     * @returns {SourceClone} The clone AudioBufferSourceNode.\n     */\n    public cloneBufferSource(): SourceClone\n    {\n        const orig: AudioBufferSourceNode = this.bufferSource;\n        const source: AudioBufferSourceNode = this.context.audioContext.createBufferSource();\n\n        source.buffer = orig.buffer;\n        WebAudioUtils.setParamValue(source.playbackRate, orig.playbackRate.value);\n        source.loop = orig.loop;\n\n        const gain: GainNode = this.context.audioContext.createGain();\n\n        source.connect(gain);\n        gain.connect(this.destination);\n\n        return { source, gain };\n    }\n\n    /**\n     * Get buffer size of `ScriptProcessorNode`.\n     * @readonly\n     */\n    get bufferSize(): number\n    {\n        return this.script.bufferSize;\n    }\n}\n\nexport type { SourceClone };\nexport { WebAudioNodes };\n","import { DOMAdapter } from 'pixi.js';\nimport { Filter } from '../filters/Filter';\nimport { IMedia } from '../interfaces/IMedia';\nimport { LoadedCallback, Sound } from '../Sound';\nimport { WebAudioContext } from './WebAudioContext';\nimport { WebAudioInstance } from './WebAudioInstance';\nimport { WebAudioNodes } from './WebAudioNodes';\n\n/**\n * Represents a single sound element. Can be used to play, pause, etc. sound instances.\n * @memberof webaudio\n */\nclass WebAudioMedia implements IMedia\n{\n    /**\n     * Reference to the parent Sound container.\n     * @readonly\n     */\n    public parent: Sound;\n\n    /**\n     * The file buffer to load.\n     * @readonly\n     */\n    public source: ArrayBuffer | AudioBuffer;\n\n    /** Instance of the chain builder. */\n    private _nodes: WebAudioNodes;\n\n    /** Instance of the source node. */\n    private _source: AudioBufferSourceNode;\n\n    /**\n     * Re-initialize without constructing.\n     * @param parent - - Instance of parent Sound container\n     */\n    public init(parent: Sound): void\n    {\n        this.parent = parent;\n        this._nodes = new WebAudioNodes(this.context);\n        this._source = this._nodes.bufferSource;\n        this.source = parent.options.source as ArrayBuffer | AudioBuffer;\n    }\n\n    /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */\n    public destroy(): void\n    {\n        this.parent = null;\n        this._nodes.destroy();\n        this._nodes = null;\n        try\n        {\n            this._source.buffer = null;\n        }\n        catch (err)\n        {\n            // try/catch workaround for bug in older Chrome versions\n            console.warn('Failed to set AudioBufferSourceNode.buffer to null:', err);\n        }\n        this._source = null;\n        this.source = null;\n    }\n\n    // Implement create\n    public create(): WebAudioInstance\n    {\n        return new WebAudioInstance(this);\n    }\n\n    // Implement context\n    public get context(): WebAudioContext\n    {\n        return this.parent.context as WebAudioContext;\n    }\n\n    // Implement isPlayable\n    public get isPlayable(): boolean\n    {\n        return !!this._source && !!this._source.buffer;\n    }\n\n    // Implement filters\n    public get filters(): Filter[]\n    {\n        return this._nodes.filters;\n    }\n    public set filters(filters: Filter[])\n    {\n        this._nodes.filters = filters;\n    }\n\n    // Implements duration\n    public get duration(): number\n    {\n        // eslint-disable-next-line no-console\n        console.assert(this.isPlayable, 'Sound not yet playable, no duration');\n\n        return this._source.buffer.duration;\n    }\n\n    /** Gets and sets the buffer. */\n    public get buffer(): AudioBuffer\n    {\n        return this._source.buffer;\n    }\n    public set buffer(buffer: AudioBuffer)\n    {\n        this._source.buffer = buffer;\n    }\n\n    /** Get the current chained nodes object */\n    public get nodes(): WebAudioNodes\n    {\n        return this._nodes;\n    }\n\n    // Implements load\n    public load(callback?: LoadedCallback): void\n    {\n        // Load from the arraybuffer, incase it was loaded outside\n        if (this.source)\n        {\n            this._decode(this.source, callback);\n        }\n        // Load from the file path\n        else if (this.parent.url)\n        {\n            this._loadUrl(callback);\n        }\n        else if (callback)\n        {\n            callback(new Error('sound.url or sound.source must be set'));\n        }\n        else\n        {\n            console.error('sound.url or sound.source must be set');\n        }\n    }\n\n    /** Loads a sound using XHMLHttpRequest object. */\n    private async _loadUrl(callback?: LoadedCallback): Promise<void>\n    {\n        const url: string = this.parent.url;\n        const response = await DOMAdapter.get().fetch(url);\n\n        this._decode(await response.arrayBuffer(), callback);\n    }\n\n    /**\n     * Decodes the array buffer.\n     * @param arrayBuffer - From load.\n     * @param {Function} callback - Callback optional\n     */\n    private _decode(arrayBuffer: ArrayBuffer | AudioBuffer, callback?: LoadedCallback): void\n    {\n        const audioBufferReadyFn = (err: Error, buffer: AudioBuffer) =>\n        {\n            if (err)\n            {\n                if (callback)\n                {\n                    callback(err);\n                }\n            }\n            else\n            {\n                this.parent.isLoaded = true;\n                this.buffer = buffer;\n                const instance = this.parent.autoPlayStart();\n\n                if (callback)\n                {\n                    callback(null, this.parent, instance);\n                }\n            }\n        };\n\n        if (arrayBuffer instanceof AudioBuffer)\n        {\n            audioBufferReadyFn(null, arrayBuffer);\n        }\n        else\n        {\n            const context = this.parent.context as WebAudioContext;\n\n            context.decode(arrayBuffer, audioBufferReadyFn);\n        }\n    }\n}\n\nexport { WebAudioMedia };\n","import { path } from 'pixi.js';\nimport { Filter } from './filters/Filter';\nimport { HTMLAudioMedia } from './htmlaudio/HTMLAudioMedia';\nimport { getInstance } from './instance';\nimport { IMedia, IMediaContext, IMediaInstance } from './interfaces';\nimport { SoundSprite, SoundSpriteData, SoundSprites } from './SoundSprite';\nimport { extensions, supported } from './utils/supported';\nimport { WebAudioMedia } from './webaudio/WebAudioMedia';\n\n/**\n * Options to use for creating sounds.\n */\ninterface Options\n{\n    /**\n     * `true` to immediately start preloading.\n     * @default false\n     */\n    autoPlay?: boolean;\n    /**\n     * `true` to disallow playing multiple layered instances at once.\n     * @default false\n     */\n    singleInstance?: boolean;\n    /**\n     * The amount of volume 1 = 100%.\n     * @default 1\n     */\n    volume?: number;\n    /**\n     * The playback rate where 1 is 100% speed.\n     * @default 1\n     */\n    speed?: number;\n    /**\n     * Global complete callback when play is finished.\n     * @type {Function}\n     */\n    complete?: CompleteCallback;\n    /**\n     * Call when finished loading.\n     * @type {Function}\n     */\n    loaded?: LoadedCallback;\n    /**\n     * `true` to immediately start preloading if loading from `url`.\n     */\n    preload?: boolean;\n    /**\n     * Initial loop value, `true` is loop infinitely\n     * @default false\n     */\n    loop?: boolean;\n    /**\n     * The source of the file being loaded\n     */\n    url?: string | string[];\n    /**\n     * If sound is already preloaded, available.\n     */\n    source?: ArrayBuffer | AudioBuffer | HTMLAudioElement;\n    /**\n     * The map of sprite data. Where a sprite is an object\n     * with a `start` and `end`, which are the times in seconds. Optionally, can include\n     * a `speed` amount where 1 is 100% speed.\n     */\n    sprites?: Record<string, SoundSpriteData>;\n}\n\n/**\n * Options used for sound playback.\n */\ninterface PlayOptions\n{\n    /**\n     * Start time offset in seconds.\n     * @default 0\n     */\n    start?: number;\n    /**\n     * End time in seconds.\n     */\n    end?: number;\n    /**\n     * Override default speed, default to the Sound's speed setting.\n     */\n    speed?: number;\n    /**\n    * Override default loop, default to the Sound's loop setting.\n    */\n    loop?: boolean;\n    /**\n     * Override default volume, default to the Sound's volume setting.\n     */\n    volume?: number;\n    /**\n     * The sprite to play.\n     */\n    sprite?: string;\n    /**\n     * If sound instance is muted by default.\n     * @default false\n     */\n    muted?: boolean;\n    /**\n     * Filters that apply to play.\n     * Only supported with WebAudio.\n     */\n    filters?: Filter[];\n    /**\n     * When completed.\n     * @type {Function}\n     */\n    complete?: CompleteCallback;\n    /**\n     * If not already preloaded, callback when finishes load.\n     * @type {Function}\n     */\n    loaded?: LoadedCallback;\n    /**\n     * Setting `true` will stop any playing instances. This is the same as\n     * the singleInstance property on Sound, but is play-specific.\n     */\n    singleInstance?: boolean;\n}\n\n/**\n * Callback when sound is loaded.\n * @ignore\n * @param {Error} err - The callback error.\n * @param {Sound} sound - The instance of new sound.\n * @param {IMediaInstance} instance - The instance of auto-played sound.\n */\ntype LoadedCallback = (err: Error, sound?: Sound, instance?: IMediaInstance) => void;\n\n/**\n * Callback when sound is completed.\n * @ignore\n * @param {Sound} sound - The instance of sound.\n */\ntype CompleteCallback = (sound: Sound) => void;\n\ntype SoundSpriteDataMap = Record<string, SoundSpriteData>;\n\n/**\n * Sound represents a single piece of loaded media. When playing a sound {@link IMediaInstance} objects\n * are created. Properties such a `volume`, `pause`, `mute`, `speed`, etc will have an effect on all instances.\n */\nclass Sound\n{\n    /** Pool of instances */\n    private static _pool: IMediaInstance[] = [];\n\n    /**\n     * `true` if the buffer is loaded.\n     * @default false\n     */\n    public isLoaded: boolean;\n\n    /**\n     * `true` if the sound is currently being played.\n     * @default false\n     * @readonly\n     */\n    public isPlaying: boolean;\n\n    /**\n     * true to start playing immediate after load.\n     * @default false\n     * @readonly\n     */\n    public autoPlay: boolean;\n\n    /**\n     * `true` to disallow playing multiple layered instances at once.\n     * @default false\n     */\n    public singleInstance: boolean;\n\n    /**\n     * `true` to immediately start preloading.\n     * @default false\n     * @readonly\n     */\n    public preload: boolean;\n\n    /**\n     * The file source to load.\n     * @readonly\n     */\n    public url: string;\n\n    /**\n     * The constructor options.\n     * @readonly\n     */\n    public options: Options;\n\n    /** The audio source */\n    public media: IMedia;\n\n    /** The list of play calls while waiting to preload the sound. */\n    private _preloadQueue: (() => void)[] | null;\n\n    /** The collection of instances being played. */\n    private _instances: IMediaInstance[];\n\n    /** The user defined sound sprites. */\n    private _sprites: SoundSprites;\n\n    /** The options when auto-playing. */\n    private _autoPlayOptions: PlayOptions;\n\n    /** The internal volume. */\n    private _volume: number;\n\n    /** The internal paused state. */\n    private _paused: boolean;\n\n    /** The internal muted state. */\n    private _muted: boolean;\n\n    /** The internal volume. */\n    private _loop: boolean;\n\n    /** The internal playbackRate */\n    private _speed: number;\n\n    /**\n     * Create a new sound instance from source.\n     * @param source - Either the path or url to the source file.\n     *        or the object of options to use.\n     * @return Created sound instance.\n     */\n    public static from(source: string | string[] | Options | ArrayBuffer | HTMLAudioElement | AudioBuffer): Sound\n    {\n        let options: Options = {};\n\n        if (typeof source === 'string')\n        {\n            options.url = source as string;\n        }\n        else if (source instanceof ArrayBuffer || source instanceof AudioBuffer || source instanceof HTMLAudioElement)\n        {\n            options.source = source;\n        }\n        else if (Array.isArray(source))\n        {\n            options.url = source;\n        }\n        else\n        {\n            options = source;\n        }\n\n        // Default settings\n        options = {\n            autoPlay: false,\n            singleInstance: false,\n            url: null,\n            source: null,\n            preload: false,\n            volume: 1,\n            speed: 1,\n            complete: null,\n            loaded: null,\n            loop: false, ...options\n        };\n\n        Object.freeze(options);\n\n        const media: IMedia = getInstance().useLegacy\n            ? new HTMLAudioMedia()\n            : new WebAudioMedia();\n\n        return new Sound(media, options);\n    }\n\n    /**\n     * Use `Sound.from`\n     * @ignore\n     */\n    constructor(media: IMedia, options: Options)\n    {\n        this.media = media;\n        this.options = options;\n        this._instances = [];\n        this._sprites = {};\n\n        this.media.init(this);\n\n        const complete = options.complete;\n\n        this._autoPlayOptions = complete ? { complete } : null;\n        this.isLoaded = false;\n        this._preloadQueue = null;\n        this.isPlaying = false;\n        this.autoPlay = options.autoPlay;\n        this.singleInstance = options.singleInstance;\n        this.preload = options.preload || this.autoPlay;\n\n        this.url = Array.isArray(options.url)\n            ? this.preferUrl(options.url)\n            : options.url;\n        this.speed = options.speed;\n        this.volume = options.volume;\n        this.loop = options.loop;\n\n        if (options.sprites)\n        {\n            this.addSprites(options.sprites);\n        }\n\n        if (this.preload)\n        {\n            this._preload(options.loaded);\n        }\n    }\n\n    /**\n     * Internal help for resolving which file to use if there are multiple provide\n     * this is especially helpful for working with bundlers (non Assets loading).\n     */\n    private preferUrl(urls: string[]): string\n    {\n        const [file] = urls\n            .map((url) => ({ url, ext: path.extname(url).slice(1) }))\n            .filter(({ ext }) => supported[ext])\n            .sort((a, b) => extensions.indexOf(a.ext) - extensions.indexOf(b.ext));\n\n        if (!file)\n        {\n            throw new Error('No supported file type found');\n        }\n\n        return file.url;\n    }\n\n    /** Instance of the media context. */\n    public get context(): IMediaContext\n    {\n        return getInstance().context;\n    }\n\n    /** Stops all the instances of this sound from playing. */\n    public pause(): this\n    {\n        this.isPlaying = false;\n        this.paused = true;\n\n        return this;\n    }\n\n    /** Resuming all the instances of this sound from playing */\n    public resume(): this\n    {\n        this.isPlaying = this._instances.length > 0;\n        this.paused = false;\n\n        return this;\n    }\n\n    /** Stops all the instances of this sound from playing. */\n    public get paused(): boolean\n    {\n        return this._paused;\n    }\n    public set paused(paused: boolean)\n    {\n        this._paused = paused;\n        this.refreshPaused();\n    }\n\n    /** The playback rate. */\n    public get speed(): number\n    {\n        return this._speed;\n    }\n    public set speed(speed: number)\n    {\n        this._speed = speed;\n        this.refresh();\n    }\n\n    /** Set the filters. Only supported with WebAudio. */\n    public get filters(): Filter[]\n    {\n        return this.media.filters;\n    }\n    public set filters(filters: Filter[])\n    {\n        this.media.filters = filters;\n    }\n\n    /**\n     * Add a sound sprite, which is a saved instance of a longer sound.\n     * Similar to an image spritesheet.\n     * @param alias - The unique name of the sound sprite.\n     * @param data - Either completed function or play options.\n     */\n    public addSprites(alias: string, data: SoundSpriteData): SoundSprite;\n\n    /**\n     * Convenience method to add more than one sprite add a time.\n     * @param data - Map of sounds to add where the key is the alias,\n     *        and the data are configuration options.\n     * @return The map of sound sprites added.\n     */\n    public addSprites(data: SoundSpriteDataMap): SoundSprites;\n\n    /**\n     * @ignore\n     */\n    public addSprites(source: string | SoundSpriteDataMap, data?: SoundSpriteData): any\n    {\n        if (typeof source === 'object')\n        {\n            const results: SoundSprites = {};\n\n            for (const alias in source)\n            {\n                results[alias] = this.addSprites(alias, source[alias]);\n            }\n\n            return results;\n        }\n\n        // eslint-disable-next-line no-console\n        console.assert(!this._sprites[source], `Alias ${source} is already taken`);\n        const sprite = new SoundSprite(this, data);\n\n        this._sprites[source] = sprite;\n\n        return sprite;\n    }\n\n    /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */\n    public destroy(): void\n    {\n        this._removeInstances();\n        this.removeSprites();\n        this.media.destroy();\n        this.media = null;\n        this._sprites = null;\n        this._instances = null;\n    }\n\n    /**\n     * Remove a sound sprite.\n     * @param alias - The unique name of the sound sprite, if alias is omitted, removes all sprites.\n     */\n    public removeSprites(alias?: string): Sound\n    {\n        if (!alias)\n        {\n            for (const name in this._sprites)\n            {\n                this.removeSprites(name);\n            }\n        }\n        else\n        {\n            const sprite: SoundSprite = this._sprites[alias];\n\n            if (sprite !== undefined)\n            {\n                sprite.destroy();\n                delete this._sprites[alias];\n            }\n        }\n\n        return this;\n    }\n\n    /** If the current sound is playable (loaded). */\n    public get isPlayable(): boolean\n    {\n        return this.isLoaded && this.media && this.media.isPlayable;\n    }\n\n    /** Stops all the instances of this sound from playing. */\n    public stop(): this\n    {\n        if (!this.isPlayable)\n        {\n            this.autoPlay = false;\n            this._autoPlayOptions = null;\n\n            return this;\n        }\n        this.isPlaying = false;\n\n        // Go in reverse order so we don't skip items\n        for (let i = this._instances.length - 1; i >= 0; i--)\n        {\n            this._instances[i].stop();\n        }\n\n        return this;\n    }\n\n    /**\n     * Play a sound sprite, which is a saved instance of a longer sound.\n     * Similar to an image spritesheet.\n     * @method play\n     * @instance\n     * @param alias - The unique name of the sound sprite.\n     * @param {Function} callback - Callback when completed.\n     * @return The sound instance,\n     *        this cannot be reused after it is done playing. Returns a Promise if the sound\n     *        has not yet loaded.\n     */\n    public play(alias: string, callback?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>;\n\n    /**\n     * Plays the sound.\n     * @method play\n     * @instance\n     * @param {Function|PlayOptions} source - Either completed function or play options.\n     * @param {Function} callback - Callback when completed.\n     * @return The sound instance,\n     *        this cannot be reused after it is done playing. Returns a Promise if the sound\n     *        has not yet loaded.\n     */\n    public play(source?: string | PlayOptions | CompleteCallback,\n        callback?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>;\n\n    // Overloaded function\n    public play(source?: string | PlayOptions | CompleteCallback,\n        complete?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>\n    {\n        let options: PlayOptions;\n\n        if (typeof source === 'string')\n        {\n            const sprite: string = source as string;\n\n            options = { sprite, loop: this.loop, complete };\n        }\n        else if (typeof source === 'function')\n        {\n            options = {};\n            options.complete = source as CompleteCallback;\n        }\n        else\n        {\n            options = source as PlayOptions;\n        }\n\n        options = {\n            complete: null,\n            loaded: null,\n            sprite: null,\n            end: null,\n            start: 0,\n            volume: 1,\n            speed: 1,\n            muted: false,\n            loop: false, ...(options || {})\n        };\n\n        // A sprite is specified, add the options\n        if (options.sprite)\n        {\n            const alias: string = options.sprite;\n\n            // eslint-disable-next-line no-console\n            console.assert(!!this._sprites[alias], `Alias ${alias} is not available`);\n            const sprite: SoundSprite = this._sprites[alias];\n\n            options.start = sprite.start + (options.start || 0);\n            options.end = sprite.end;\n            options.speed = sprite.speed || 1;\n            options.loop = sprite.loop || options.loop;\n            delete options.sprite;\n        }\n\n        // @deprecated offset option\n        if ((options as any).offset)\n        {\n            options.start = (options as any).offset as number;\n        }\n\n        // if not yet playable, ignore\n        // - usefull when the sound download isnt yet completed\n        if (!this.isLoaded)\n        {\n            // Handle the case when trying to play a sound that is not yet loaded\n            // We'll add it to a queue to play after initial load finishes\n            if (this._preloadQueue)\n            {\n                return new Promise<IMediaInstance>((resolve) =>\n                {\n                    this._preloadQueue.push(() =>\n                    {\n                        resolve(this.play(options));\n                    });\n                });\n            }\n\n            this._preloadQueue = [];\n            this.autoPlay = true;\n            this._autoPlayOptions = options;\n\n            return new Promise<IMediaInstance>((resolve, reject) =>\n            {\n                this._preload((err: Error, sound: Sound, media: IMediaInstance) =>\n                {\n                    this._preloadQueue.forEach((resolve) => resolve());\n                    this._preloadQueue = null;\n\n                    if (err)\n                    {\n                        reject(err);\n                    }\n                    else\n                    {\n                        if (options.loaded)\n                        {\n                            options.loaded(err, sound, media);\n                        }\n                        resolve(media);\n                    }\n                });\n            });\n        }\n\n        // Stop all sounds\n        if (this.singleInstance || options.singleInstance)\n        {\n            this._removeInstances();\n        }\n\n        // clone the bufferSource\n        const instance = this._createInstance();\n\n        this._instances.push(instance);\n        this.isPlaying = true;\n        instance.once('end', () =>\n        {\n            if (options.complete)\n            {\n                options.complete(this);\n            }\n            this._onComplete(instance);\n        });\n        instance.once('stop', () =>\n        {\n            this._onComplete(instance);\n        });\n\n        instance.play(options);\n\n        return instance;\n    }\n\n    /** Internal only, speed, loop, volume change occured. */\n    public refresh(): void\n    {\n        const len = this._instances.length;\n\n        for (let i = 0; i < len; i++)\n        {\n            this._instances[i].refresh();\n        }\n    }\n\n    /** Handle changes in paused state. Internal only. */\n    public refreshPaused(): void\n    {\n        const len = this._instances.length;\n\n        for (let i = 0; i < len; i++)\n        {\n            this._instances[i].refreshPaused();\n        }\n    }\n\n    /** Gets and sets the volume. */\n    public get volume(): number\n    {\n        return this._volume;\n    }\n    public set volume(volume: number)\n    {\n        this._volume = volume;\n        this.refresh();\n    }\n\n    /** Gets and sets the muted flag. */\n    public get muted(): boolean\n    {\n        return this._muted;\n    }\n    public set muted(muted: boolean)\n    {\n        this._muted = muted;\n        this.refresh();\n    }\n\n    /** Gets and sets the looping. */\n    public get loop(): boolean\n    {\n        return this._loop;\n    }\n    public set loop(loop: boolean)\n    {\n        this._loop = loop;\n        this.refresh();\n    }\n\n    /** Starts the preloading of sound. */\n    private _preload(callback?: LoadedCallback): void\n    {\n        this.media.load(callback);\n    }\n\n    /** Gets the list of instances that are currently being played of this sound. */\n    public get instances(): IMediaInstance[]\n    {\n        return this._instances;\n    }\n\n    /** Get the map of sprites. */\n    public get sprites(): SoundSprites\n    {\n        return this._sprites;\n    }\n\n    /** Get the duration of the audio in seconds. */\n    public get duration(): number\n    {\n        return this.media.duration;\n    }\n\n    /** Auto play the first instance. */\n    public autoPlayStart(): IMediaInstance\n    {\n        let instance: IMediaInstance;\n\n        if (this.autoPlay)\n        {\n            instance = this.play(this._autoPlayOptions) as IMediaInstance;\n        }\n\n        return instance;\n    }\n\n    /** Removes all instances. */\n    private _removeInstances(): void\n    {\n        // destroying also stops\n        for (let i = this._instances.length - 1; i >= 0; i--)\n        {\n            this._poolInstance(this._instances[i]);\n        }\n        this._instances.length = 0;\n    }\n\n    /**\n     * Sound instance completed.\n     * @param instance\n     */\n    private _onComplete(instance: IMediaInstance): void\n    {\n        if (this._instances)\n        {\n            const index = this._instances.indexOf(instance);\n\n            if (index > -1)\n            {\n                this._instances.splice(index, 1);\n            }\n            this.isPlaying = this._instances.length > 0;\n        }\n        this._poolInstance(instance);\n    }\n\n    /** Create a new instance. */\n    private _createInstance(): IMediaInstance\n    {\n        if (Sound._pool.length > 0)\n        {\n            const instance: IMediaInstance = Sound._pool.pop();\n\n            instance.init(this.media);\n\n            return instance;\n        }\n\n        return this.media.create();\n    }\n\n    /**\n     * Destroy/recycling the instance object.\n     * @param instance - Instance to recycle\n     */\n    private _poolInstance(instance: IMediaInstance): void\n    {\n        instance.destroy();\n        // Add it if it isn't already added\n        if (Sound._pool.indexOf(instance) < 0)\n        {\n            Sound._pool.push(instance);\n        }\n    }\n}\n\nexport { Sound };\nexport type {\n    CompleteCallback,\n    LoadedCallback,\n    Options,\n    PlayOptions,\n    SoundSpriteDataMap\n};\n","import { EventEmitter } from 'pixi.js';\nimport { Filterable } from '../Filterable';\nimport { IMediaContext } from '../interfaces';\n\n/**\n * Main class to handle WebAudio API. There's a simple chain\n * of AudioNode elements: analyser > compressor > context.destination.\n * any filters that are added are inserted between the analyser and compressor nodes\n * @memberof webaudio\n */\nclass WebAudioContext extends Filterable implements IMediaContext\n{\n    /**\n     * Context Compressor node\n     * @readonly\n     */\n    public compressor: DynamicsCompressorNode;\n\n    /**\n     * Context Analyser node\n     * @readonly\n     */\n    public analyser: AnalyserNode;\n\n    /**\n     * Global speed of all sounds\n     * @readonly\n     */\n    public speed: number;\n\n    /**\n     * Sets the muted state.\n     * @default false\n     */\n    public muted: boolean;\n\n    /**\n     * Sets the volume from 0 to 1.\n     * @default 1\n     */\n    public volume: number;\n\n    /**\n     * Handle global events\n     * @type {PIXI.EventEmitter}\n     */\n    public events: EventEmitter;\n\n    /** The instance of the AudioContext for WebAudio API. */\n    private _ctx: AudioContext;\n\n    /** The instance of the OfflineAudioContext for fast decoding audio. */\n    private _offlineCtx: OfflineAudioContext;\n\n    /** Current paused status */\n    private _paused: boolean;\n\n    /**\n     * Indicated whether audio on iOS has been unlocked, which requires a touchend/mousedown event that plays an\n     * empty sound.\n     */\n    private _locked: boolean;\n\n    /** The paused state when blurring the current window */\n    private _pausedOnBlur: boolean;\n\n    /** Set to false ignore suspending when window is blurred */\n    public autoPause = true;\n\n    constructor()\n    {\n        const win: any = window as any;\n        const ctx = new WebAudioContext.AudioContext();\n        const compressor: DynamicsCompressorNode = ctx.createDynamicsCompressor();\n        const analyser: AnalyserNode = ctx.createAnalyser();\n\n        // setup the end of the node chain\n        analyser.connect(compressor);\n        compressor.connect(ctx.destination);\n\n        super(analyser, compressor);\n\n        this._ctx = ctx;\n        // ios11 safari's webkitOfflineAudioContext allows only 44100 Hz sample rate\n        //\n        // For the sample rate value passed to OfflineAudioContext constructor,\n        // all browsers are required to support a range of 8000 to 96000.\n        // Reference:\n        // https://www.w3.org/TR/webaudio/#dom-offlineaudiocontext-offlineaudiocontext-numberofchannels-length-samplerate\n        this._offlineCtx = new WebAudioContext.OfflineAudioContext(1, 2,\n            (win.OfflineAudioContext) ? Math.max(8000, Math.min(96000, ctx.sampleRate)) : 44100);\n\n        this.compressor = compressor;\n        this.analyser = analyser;\n        this.events = new EventEmitter();\n\n        // Set the defaults\n        this.volume = 1;\n        this.speed = 1;\n        this.muted = false;\n        this.paused = false;\n\n        this._locked = ctx.state === 'suspended' && ('ontouchstart' in globalThis || 'onclick' in globalThis);\n\n        // Listen for document level clicks to unlock WebAudio. See the _unlock method.\n        if (this._locked)\n        {\n            this._unlock(); // When played inside of a touch event, this will enable audio on iOS immediately.\n            this._unlock = this._unlock.bind(this);\n            document.addEventListener('mousedown', this._unlock, true);\n            document.addEventListener('touchstart', this._unlock, true);\n            document.addEventListener('touchend', this._unlock, true);\n        }\n\n        this.onFocus = this.onFocus.bind(this);\n        this.onBlur = this.onBlur.bind(this);\n        globalThis.addEventListener('focus', this.onFocus);\n        globalThis.addEventListener('blur', this.onBlur);\n    }\n\n    /** Handle mobile WebAudio context resume */\n    private onFocus(): void\n    {\n        if (!this.autoPause)\n        {\n            return;\n        }\n        // Safari uses the non-standard \"interrupted\" state in some cases\n        // such as when the app loses focus because the screen is locked\n        // or when the user switches to another app.\n        const state = this._ctx.state as 'suspended' | 'interrupted';\n\n        if (state === 'suspended' || state === 'interrupted' || !this._locked)\n        {\n            this.paused = this._pausedOnBlur;\n            this.refreshPaused();\n        }\n    }\n\n    /** Handle mobile WebAudio context suspend */\n    private onBlur(): void\n    {\n        if (!this.autoPause)\n        {\n            return;\n        }\n        if (!this._locked)\n        {\n            this._pausedOnBlur = this._paused;\n            this.paused = true;\n            this.refreshPaused();\n        }\n    }\n\n    /**\n     * Try to unlock audio on iOS. This is triggered from either WebAudio plugin setup (which will work if inside of\n     * a `mousedown` or `touchend` event stack), or the first document touchend/mousedown event. If it fails (touchend\n     * will fail if the user presses for too long, indicating a scroll event instead of a click event.\n     *\n     * Note that earlier versions of iOS supported `touchstart` for this, but iOS9 removed this functionality. Adding\n     * a `touchstart` event to support older platforms may preclude a `mousedown` even from getting fired on iOS9, so we\n     * stick with `mousedown` and `touchend`.\n     */\n    private _unlock(): void\n    {\n        if (!this._locked)\n        {\n            return;\n        }\n        this.playEmptySound();\n        if (this._ctx.state === 'running')\n        {\n            document.removeEventListener('mousedown', this._unlock, true);\n            document.removeEventListener('touchend', this._unlock, true);\n            document.removeEventListener('touchstart', this._unlock, true);\n            this._locked = false;\n        }\n    }\n\n    /**\n     * Plays an empty sound in the web audio context.  This is used to enable web audio on iOS devices, as they\n     * require the first sound to be played inside of a user initiated event (touch/click).\n     */\n    public playEmptySound(): void\n    {\n        const source = this._ctx.createBufferSource();\n\n        source.buffer = this._ctx.createBuffer(1, 1, 22050);\n        source.connect(this._ctx.destination);\n        source.start(0, 0, 0);\n        if (source.context.state === 'suspended')\n        {\n            (source.context as AudioContext).resume();\n        }\n    }\n\n    /**\n     * Get AudioContext class, if not supported returns `null`\n     * @type {AudioContext}\n     * @readonly\n     */\n    public static get AudioContext(): typeof AudioContext\n    {\n        const win: any = window as any;\n\n        return (\n            win.AudioContext\n            || win.webkitAudioContext\n            || null\n        );\n    }\n\n    /**\n     * Get OfflineAudioContext class, if not supported returns `null`\n     * @type {OfflineAudioContext}\n     * @readonly\n     */\n    public static get OfflineAudioContext(): typeof OfflineAudioContext\n    {\n        const win: any = window as any;\n\n        return (\n            win.OfflineAudioContext\n            || win.webkitOfflineAudioContext\n            || null\n        );\n    }\n\n    /** Destroy this context. */\n    public destroy(): void\n    {\n        super.destroy();\n\n        const ctx: any = this._ctx as any;\n        // check if browser supports AudioContext.close()\n\n        if (typeof ctx.close !== 'undefined')\n        {\n            ctx.close();\n        }\n        globalThis.removeEventListener('focus', this.onFocus);\n        globalThis.removeEventListener('blur', this.onBlur);\n        this.events.removeAllListeners();\n        this.analyser.disconnect();\n        this.compressor.disconnect();\n        this.analyser = null;\n        this.compressor = null;\n        this.events = null;\n        this._offlineCtx = null;\n        this._ctx = null;\n    }\n\n    /**\n     * The WebAudio API AudioContext object.\n     * @readonly\n     * @type {AudioContext}\n     */\n    public get audioContext(): AudioContext\n    {\n        return this._ctx;\n    }\n\n    /**\n     * The WebAudio API OfflineAudioContext object.\n     * @readonly\n     * @type {OfflineAudioContext}\n     */\n    public get offlineContext(): OfflineAudioContext\n    {\n        return this._offlineCtx;\n    }\n\n    /**\n     * Pauses all sounds, even though we handle this at the instance\n     * level, we'll also pause the audioContext so that the\n     * time used to compute progress isn't messed up.\n     * @default false\n     */\n    public set paused(paused: boolean)\n    {\n        if (paused && this._ctx.state === 'running')\n        {\n            this._ctx.suspend();\n        }\n        else if (!paused && this._ctx.state === 'suspended')\n        {\n            this._ctx.resume();\n        }\n        this._paused = paused;\n    }\n    public get paused(): boolean\n    {\n        return this._paused;\n    }\n\n    /** Emit event when muted, volume or speed changes */\n    public refresh(): void\n    {\n        this.events.emit('refresh');\n    }\n\n    /** Emit event when muted, volume or speed changes */\n    public refreshPaused(): void\n    {\n        this.events.emit('refreshPaused');\n    }\n\n    /**\n     * Toggles the muted state.\n     * @return The current muted state.\n     */\n    public toggleMute(): boolean\n    {\n        this.muted = !this.muted;\n        this.refresh();\n\n        return this.muted;\n    }\n\n    /**\n     * Toggles the paused state.\n     * @return The current muted state.\n     */\n    public togglePause(): boolean\n    {\n        this.paused = !this.paused;\n        this.refreshPaused();\n\n        return this._paused;\n    }\n\n    /**\n     * Decode the audio data\n     * @param arrayBuffer - Buffer from loader\n     * @param callback - When completed, error and audioBuffer are parameters.\n     */\n    public decode(arrayBuffer: ArrayBuffer, callback: (err?: Error, buffer?: AudioBuffer) => void): void\n    {\n        const handleError = (err: Error) =>\n        {\n            callback(new Error(err?.message || 'Unable to decode file'));\n        };\n        const result = this._offlineCtx.decodeAudioData(\n            arrayBuffer, (buffer: AudioBuffer) =>\n            {\n                callback(null, buffer);\n            },\n            handleError,\n        );\n        // Reference: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData\n        // decodeAudioData return value: Void, or a Promise object that fulfills with the decodedData.\n\n        if (result)\n        {\n            result.catch(handleError);\n        }\n    }\n}\n\nexport { WebAudioContext };\n","import { Filter } from './filters/Filter';\nimport { HTMLAudioContext } from './htmlaudio/HTMLAudioContext';\nimport { IMediaContext } from './interfaces/IMediaContext';\nimport { IMediaInstance } from './interfaces/IMediaInstance';\nimport { CompleteCallback, Options, PlayOptions, Sound } from './Sound';\nimport { WebAudioContext } from './webaudio/WebAudioContext';\n\ntype SoundSourceMap = Record<string, Options | string | ArrayBuffer | AudioBuffer | HTMLAudioElement>;\ntype SoundMap = Record<string, Sound>;\n\n/**\n * Manages the playback of sounds. This is the main class for PixiJS Sound. If you're\n * using the browser-based bundled this is `PIXI.sound`. Otherwise, you can do this:\n * @example\n * import { sound } from '@pixi/sound';\n *\n * // sound is an instance of SoundLibrary\n * sound.add('my-sound', 'path/to/file.mp3');\n * sound.play('my-sound');\n */\nclass SoundLibrary\n{\n    /**\n     * For legacy approach for Audio. Instead of using WebAudio API\n     * for playback of sounds, it will use HTML5 `<audio>` element.\n     */\n    private _useLegacy: boolean;\n\n    /** The global context to use. */\n    private _context: IMediaContext;\n\n    /** The WebAudio specific context */\n    private _webAudioContext: WebAudioContext;\n\n    /** The HTML Audio (legacy) context. */\n    private _htmlAudioContext: HTMLAudioContext;\n\n    /** The map of all sounds by alias. */\n    private _sounds: SoundMap;\n\n    constructor()\n    {\n        this.init();\n    }\n\n    /**\n     * Re-initialize the sound library, this will\n     * recreate the AudioContext. If there's a hardware-failure\n     * call `close` and then `init`.\n     * @return Sound instance\n     */\n    public init(): this\n    {\n        if (this.supported)\n        {\n            this._webAudioContext = new WebAudioContext();\n        }\n        this._htmlAudioContext = new HTMLAudioContext();\n        this._sounds = {};\n        this.useLegacy = !this.supported;\n\n        return this;\n    }\n\n    /**\n     * The global context to use.\n     * @readonly\n     */\n    public get context(): IMediaContext\n    {\n        return this._context;\n    }\n\n    /**\n     * Apply filters to all sounds. Can be useful\n     * for setting global planning or global effects.\n     * **Only supported with WebAudio.**\n     * @example\n     * import { sound, filters } from '@pixi/sound';\n     * // Adds a filter to pan all output left\n     * sound.filtersAll = [\n     *     new filters.StereoFilter(-1)\n     * ];\n     */\n    public get filtersAll(): Filter[]\n    {\n        if (!this.useLegacy)\n        {\n            return this._context.filters;\n        }\n\n        return [];\n    }\n    public set filtersAll(filtersAll: Filter[])\n    {\n        if (!this.useLegacy)\n        {\n            this._context.filters = filtersAll;\n        }\n    }\n\n    /**\n     * `true` if WebAudio is supported on the current browser.\n     */\n    public get supported(): boolean\n    {\n        return WebAudioContext.AudioContext !== null;\n    }\n\n    /**\n     * Register an existing sound with the library cache.\n     * @method add\n     * @instance\n     * @param {string} alias - The sound alias reference.\n     * @param {Sound} sound - Sound reference to use.\n     * @return {Sound} Instance of the Sound object.\n     */\n\n    /**\n     * Adds a new sound by alias.\n     * @param alias - The sound alias reference.\n     * @param {ArrayBuffer|AudioBuffer|String|Options|HTMLAudioElement} options - Either the path or url to the source file.\n     *        or the object of options to use.\n     * @return Instance of the Sound object.\n     */\n    public add(alias: string, options: Options | string | ArrayBuffer | AudioBuffer | HTMLAudioElement | Sound): Sound;\n\n    /**\n     * Adds multiple sounds at once.\n     * @param map - Map of sounds to add, the key is the alias, the value is the\n     *        `string`, `ArrayBuffer`, `AudioBuffer`, `HTMLAudioElement` or the list of options\n     *        (see {@link Options} for full options).\n     * @param globalOptions - The default options for all sounds.\n     *        if a property is defined, it will use the local property instead.\n     * @return Instance to the Sound object.\n     */\n    public add(map: SoundSourceMap, globalOptions?: Options): SoundMap;\n\n    /**\n     * @ignore\n     */\n    public add(source: string | SoundSourceMap,\n        sourceOptions?: Options | string | ArrayBuffer | AudioBuffer | HTMLAudioElement | Sound): any\n    {\n        if (typeof source === 'object')\n        {\n            const results: SoundMap = {};\n\n            for (const alias in source)\n            {\n                const options: Options = this._getOptions(\n                    source[alias],\n                    sourceOptions as Options,\n                );\n\n                results[alias] = this.add(alias, options);\n            }\n\n            return results;\n        }\n\n        // eslint-disable-next-line no-console\n        console.assert(!this._sounds[source], `Sound with alias ${source} already exists.`);\n\n        if (sourceOptions instanceof Sound)\n        {\n            this._sounds[source] = sourceOptions;\n\n            return sourceOptions;\n        }\n\n        const options: Options = this._getOptions(sourceOptions);\n        const sound: Sound = Sound.from(options);\n\n        this._sounds[source] = sound;\n\n        return sound;\n    }\n\n    /**\n     * Internal methods for getting the options object\n     * @private\n     * @param source - The source options\n     * @param overrides - Override default options\n     * @return The construction options\n     */\n    private _getOptions(source: string | ArrayBuffer | AudioBuffer | HTMLAudioElement | Options,\n        overrides?: Options): Options\n    {\n        let options: Options;\n\n        if (typeof source === 'string')\n        {\n            options = { url: source };\n        }\n        else if (Array.isArray(source))\n        {\n            options = { url: source };\n        }\n        else if (source instanceof ArrayBuffer || source instanceof AudioBuffer || source instanceof HTMLAudioElement)\n        {\n            options = { source };\n        }\n        else\n        {\n            options = source as Options;\n        }\n        options = { ...options, ...(overrides || {}) };\n\n        return options;\n    }\n\n    /**\n     * Do not use WebAudio, force the use of legacy. This **must** be called before loading any files.\n     */\n    public get useLegacy(): boolean\n    {\n        return this._useLegacy;\n    }\n    public set useLegacy(legacy: boolean)\n    {\n        this._useLegacy = legacy;\n\n        // Set the context to use\n        this._context = (!legacy && this.supported)\n            ? this._webAudioContext\n            : this._htmlAudioContext;\n    }\n\n    /**\n     * This disables auto-pause all playback when the window blurs (WebAudio only).\n     * This is helpful to keep from playing sounds when the user switches tabs.\n     * However, if you're running content within an iframe, this may be undesirable\n     * and you should disable (set to `true`) this behavior.\n     * @default false\n     */\n    public get disableAutoPause(): boolean\n    {\n        return !this._webAudioContext.autoPause;\n    }\n    public set disableAutoPause(autoPause: boolean)\n    {\n        this._webAudioContext.autoPause = !autoPause;\n    }\n\n    /**\n     * Removes a sound by alias.\n     * @param alias - The sound alias reference.\n     * @return Instance for chaining.\n     */\n    public remove(alias: string): this\n    {\n        this.exists(alias, true);\n        this._sounds[alias].destroy();\n        delete this._sounds[alias];\n\n        return this;\n    }\n\n    /**\n     * Set the global volume for all sounds. To set per-sound volume see {@link SoundLibrary#volume}.\n     */\n    public get volumeAll(): number\n    {\n        return this._context.volume;\n    }\n    public set volumeAll(volume: number)\n    {\n        this._context.volume = volume;\n        this._context.refresh();\n    }\n\n    /**\n     * Set the global speed for all sounds. To set per-sound speed see {@link SoundLibrary#speed}.\n     */\n    public get speedAll(): number\n    {\n        return this._context.speed;\n    }\n    public set speedAll(speed: number)\n    {\n        this._context.speed = speed;\n        this._context.refresh();\n    }\n\n    /**\n     * Toggle paused property for all sounds.\n     * @return `true` if all sounds are paused.\n     */\n    public togglePauseAll(): boolean\n    {\n        return this._context.togglePause();\n    }\n\n    /**\n     * Pauses any playing sounds.\n     * @return Instance for chaining.\n     */\n    public pauseAll(): this\n    {\n        this._context.paused = true;\n        this._context.refreshPaused();\n\n        return this;\n    }\n\n    /**\n     * Resumes any sounds.\n     * @return Instance for chaining.\n     */\n    public resumeAll(): this\n    {\n        this._context.paused = false;\n        this._context.refreshPaused();\n\n        return this;\n    }\n\n    /**\n     * Toggle muted property for all sounds.\n     * @return `true` if all sounds are muted.\n     */\n    public toggleMuteAll(): boolean\n    {\n        return this._context.toggleMute();\n    }\n\n    /**\n     * Mutes all playing sounds.\n     * @return Instance for chaining.\n     */\n    public muteAll(): this\n    {\n        this._context.muted = true;\n        this._context.refresh();\n\n        return this;\n    }\n\n    /**\n     * Unmutes all playing sounds.\n     * @return Instance for chaining.\n     */\n    public unmuteAll(): this\n    {\n        this._context.muted = false;\n        this._context.refresh();\n\n        return this;\n    }\n\n    /**\n     * Stops and removes all sounds. They cannot be used after this.\n     * @return Instance for chaining.\n     */\n    public removeAll(): this\n    {\n        for (const alias in this._sounds)\n        {\n            this._sounds[alias].destroy();\n            delete this._sounds[alias];\n        }\n\n        return this;\n    }\n\n    /**\n     * Stops all sounds.\n     * @return Instance for chaining.\n     */\n    public stopAll(): this\n    {\n        for (const alias in this._sounds)\n        {\n            this._sounds[alias].stop();\n        }\n\n        return this;\n    }\n\n    /**\n     * Checks if a sound by alias exists.\n     * @param alias - Check for alias.\n     * @param assert - Whether enable console.assert.\n     * @return true if the sound exists.\n     */\n    public exists(alias: string, assert = false): boolean\n    {\n        const exists = !!this._sounds[alias];\n\n        if (assert)\n        {\n            // eslint-disable-next-line no-console\n            console.assert(exists, `No sound matching alias '${alias}'.`);\n        }\n\n        return exists;\n    }\n\n    /**\n     * Convenience function to check to see if any sound is playing.\n     * @returns `true` if any sound is currently playing.\n     */\n    public isPlaying(): boolean\n    {\n        for (const alias in this._sounds)\n        {\n            if (this._sounds[alias].isPlaying)\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * Find a sound by alias.\n     * @param alias - The sound alias reference.\n     * @return Sound object.\n     */\n    public find(alias: string): Sound\n    {\n        this.exists(alias, true);\n\n        return this._sounds[alias];\n    }\n\n    /**\n     * Plays a sound.\n     * @method play\n     * @instance\n     * @param {string} alias - The sound alias reference.\n     * @param {string} sprite - The alias of the sprite to play.\n     * @return {IMediaInstance|null} The sound instance, this cannot be reused\n     *         after it is done playing. Returns `null` if the sound has not yet loaded.\n     */\n\n    /**\n     * Plays a sound.\n     * @param alias - The sound alias reference.\n     * @param {PlayOptions|Function} options - The options or callback when done.\n     * @return The sound instance,\n     *        this cannot be reused after it is done playing. Returns a Promise if the sound\n     *        has not yet loaded.\n     */\n    public play(\n        alias: string,\n        options?: PlayOptions | CompleteCallback | string): IMediaInstance | Promise<IMediaInstance>\n    {\n        return this.find(alias).play(options);\n    }\n\n    /**\n     * Stops a sound.\n     * @param alias - The sound alias reference.\n     * @return Sound object.\n     */\n    public stop(alias: string): Sound\n    {\n        return this.find(alias).stop();\n    }\n\n    /**\n     * Pauses a sound.\n     * @param alias - The sound alias reference.\n     * @return Sound object.\n     */\n    public pause(alias: string): Sound\n    {\n        return this.find(alias).pause();\n    }\n\n    /**\n     * Resumes a sound.\n     * @param alias - The sound alias reference.\n     * @return Instance for chaining.\n     */\n    public resume(alias: string): Sound\n    {\n        return this.find(alias).resume();\n    }\n\n    /**\n     * Get or set the volume for a sound.\n     * @param alias - The sound alias reference.\n     * @param volume - Optional current volume to set.\n     * @return The current volume.\n     */\n    public volume(alias: string, volume?: number): number\n    {\n        const sound = this.find(alias);\n\n        if (volume !== undefined)\n        {\n            sound.volume = volume;\n        }\n\n        return sound.volume;\n    }\n\n    /**\n     * Get or set the speed for a sound.\n     * @param alias - The sound alias reference.\n     * @param speed - Optional current speed to set.\n     * @return The current speed.\n     */\n    public speed(alias: string, speed?: number): number\n    {\n        const sound = this.find(alias);\n\n        if (speed !== undefined)\n        {\n            sound.speed = speed;\n        }\n\n        return sound.speed;\n    }\n\n    /**\n     * Get the length of a sound in seconds.\n     * @param alias - The sound alias reference.\n     * @return The current duration in seconds.\n     */\n    public duration(alias: string): number\n    {\n        return this.find(alias).duration;\n    }\n\n    /**\n     * Closes the sound library. This will release/destroy\n     * the AudioContext(s). Can be used safely if you want to\n     * initialize the sound library later. Use `init` method.\n     */\n    public close(): this\n    {\n        this.removeAll();\n        this._sounds = null;\n        if (this._webAudioContext)\n        {\n            this._webAudioContext.destroy();\n            this._webAudioContext = null;\n        }\n        if (this._htmlAudioContext)\n        {\n            this._htmlAudioContext.destroy();\n            this._htmlAudioContext = null;\n        }\n        this._context = null;\n\n        return this;\n    }\n}\n\nexport { SoundLibrary };\nexport type { SoundMap, SoundSourceMap };\n","import { getInstance } from '../instance';\n\n/**\n * Increment the alias for play once\n * @static\n * @default 0\n */\nlet PLAY_ID = 0;\n\n/**\n * Create a new \"Audio\" stream based on given audio path and project uri; returns the audio object.\n * @memberof utils\n * @param url - Full path of the file to play.\n * @param {Function} callback - Callback when complete.\n * @return New audio element alias.\n */\nfunction playOnce(url: string, callback?: (err?: Error) => void): string\n{\n    const alias = `alias${PLAY_ID++}`;\n\n    getInstance().add(alias, {\n        url,\n        preload: true,\n        autoPlay: true,\n        loaded: (err: Error) =>\n        {\n            if (err)\n            {\n                console.error(err);\n                getInstance().remove(alias);\n                if (callback)\n                {\n                    callback(err);\n                }\n            }\n        },\n        complete: () =>\n        {\n            getInstance().remove(alias);\n            if (callback)\n            {\n                callback(null);\n            }\n        },\n    });\n\n    return alias;\n}\n\nexport { PLAY_ID, playOnce };\n","import { CanvasSource, ICanvas, TextureSource } from 'pixi.js';\nimport { Sound } from '../Sound';\nimport { WebAudioMedia } from '../webaudio/WebAudioMedia';\n\ninterface RenderOptions\n{\n    /**\n     * Width of the render.\n     * @default 512\n     */\n    width?: number;\n    /**\n     * Height of the render.\n     * @default 128\n     */\n    height?: number;\n    /**\n     * Fill style for waveform.\n     * @default 'black'\n     */\n    fill?: string | CanvasPattern | CanvasGradient;\n}\n\n/**\n * Render image as Texture. **Only supported with WebAudio**\n * @memberof utils\n * @param sound - Instance of sound to render\n * @param options - Custom rendering options\n * @return Result texture\n */\nfunction render(sound: Sound, options?: RenderOptions): TextureSource\n{\n    const canvas: HTMLCanvasElement = document.createElement('canvas');\n\n    options = {\n        width: 512,\n        height: 128,\n        fill: 'black', ...(options || {})\n    };\n\n    canvas.width = options.width;\n    canvas.height = options.height;\n\n    const textureSource = new CanvasSource({\n        resource: canvas as ICanvas,\n    });\n\n    if (!(sound.media instanceof WebAudioMedia))\n    {\n        return textureSource;\n    }\n\n    const media: WebAudioMedia = sound.media as WebAudioMedia;\n\n    // eslint-disable-next-line no-console\n    console.assert(!!media.buffer, 'No buffer found, load first');\n\n    const context: CanvasRenderingContext2D = canvas.getContext('2d');\n\n    context.fillStyle = options.fill;\n    const data: Float32Array = media.buffer.getChannelData(0);\n    const step: number = Math.ceil(data.length / options.width);\n    const amp: number = options.height / 2;\n\n    for (let i = 0; i < options.width; i++)\n    {\n        let min = 1.0;\n        let max = -1.0;\n\n        for (let j = 0; j < step; j++)\n        {\n            const datum: number = data[(i * step) + j];\n\n            if (datum < min)\n            {\n                min = datum;\n            }\n            if (datum > max)\n            {\n                max = datum;\n            }\n        }\n        context.fillRect(i, (1 + min) * amp, 1, Math.max(1, (max - min) * amp));\n    }\n\n    return textureSource;\n}\n\nexport { render };\nexport type { RenderOptions };\n\n","import { Sound } from '../Sound';\nimport { WebAudioContext } from '../webaudio/WebAudioContext';\nimport { WebAudioMedia } from '../webaudio/WebAudioMedia';\n\n/**\n * Create a new sound for a sine wave-based tone.  **Only supported with WebAudio**\n * @memberof utils\n * @param hertz - Frequency of sound.\n * @param seconds - Duration of sound in seconds.\n * @return New sound.\n */\nfunction sineTone(hertz = 200, seconds = 1): Sound\n{\n    const sound = Sound.from({\n        singleInstance: true,\n    });\n\n    if (!(sound.media instanceof WebAudioMedia))\n    {\n        return sound;\n    }\n\n    const media = sound.media as WebAudioMedia;\n    const context = sound.context as WebAudioContext;\n\n    // set default value\n    const nChannels = 1;\n    const sampleRate = 48000;\n    const amplitude = 2;\n\n    // create the buffer\n    const buffer = context.audioContext.createBuffer(\n        nChannels,\n        seconds * sampleRate,\n        sampleRate,\n    );\n    const fArray = buffer.getChannelData(0);\n\n    // fill the buffer\n    for (let i = 0; i < fArray.length; i++)\n    {\n        const time = i / buffer.sampleRate;\n        const angle = hertz * time * 2 * Math.PI;\n\n        fArray[i] = Math.sin(angle) * amplitude;\n    }\n\n    // set the buffer\n    media.buffer = buffer;\n    sound.isLoaded = true;\n\n    return sound;\n}\n\nexport { sineTone };\n","import { AssetExtension, extensions, ExtensionType, LoaderParser, LoaderParserPriority, path, ResolvedAsset } from 'pixi.js';\nimport { getInstance } from './instance';\nimport { Options, Sound } from './Sound';\nimport { extensions as exts, mimes, supported } from './utils/supported';\n\n/** Get the alias for the sound */\nconst getAlias = (asset: ResolvedAsset) =>\n{\n    const src = asset.src;\n    let alias = asset?.alias?.[0];\n\n    if (!alias || asset.src === alias)\n    {\n        alias = path.basename(src, path.extname(src));\n    }\n\n    return alias;\n};\n\n/**\n * Simple loader plugin for loading text data.\n */\nconst soundAsset = {\n    extension: ExtensionType.Asset,\n    detection: {\n        test: async () => true,\n        add: async (formats) => [...formats, ...exts.filter((ext) => supported[ext])],\n        remove: async (formats) => formats.filter((ext) => formats.includes(ext)),\n    },\n    loader: {\n        name: 'sound',\n        extension: {\n            type: [ExtensionType.LoadParser],\n            priority: LoaderParserPriority.High,\n        },\n\n        /** Should we attempt to load this file? */\n        test(url: string): boolean\n        {\n            const ext = path.extname(url).slice(1);\n\n            return !!supported[ext] || mimes.some((mime) => url.startsWith(`data:${mime}`));\n        },\n\n        /** Load the sound file, this is mostly handled by Sound.from() */\n        async load(url: string, asset: ResolvedAsset<Omit<Options, 'url' | 'preload'>>): Promise<Sound>\n        {\n            // We'll use the internal Sound.from to load the asset\n            const sound = await new Promise<Sound>((resolve, reject) => Sound.from({\n                ...asset.data,\n                url,\n                preload: true,\n                loaded(err, sound)\n                {\n                    if (err)\n                    {\n                        reject(err);\n                    }\n                    else\n                    {\n                        resolve(sound);\n                    }\n                    asset.data?.loaded?.(err, sound);\n                },\n            }));\n\n            getInstance().add(getAlias(asset), sound);\n\n            return sound;\n        },\n\n        /** Remove the sound from the library */\n        async unload(_sound: Sound, asset: ResolvedAsset): Promise<void>\n        {\n            getInstance().remove(getAlias(asset));\n        },\n    } as LoaderParser<Sound>,\n} as AssetExtension;\n\nextensions.add(soundAsset);\n\nexport { soundAsset };\n","import * as filters from './filters';\nimport * as htmlaudio from './htmlaudio';\nimport { setInstance } from './instance';\nimport { SoundLibrary } from './SoundLibrary';\nimport * as utils from './utils';\nimport * as webaudio from './webaudio';\n\nconst sound = setInstance(new SoundLibrary());\n\nexport * from './Filterable';\nexport * from './filters/Filter';\nexport * from './interfaces';\nexport * from './Sound';\nexport * from './soundAsset';\nexport * from './SoundLibrary';\nexport * from './SoundSprite';\nexport {\n    filters,\n    htmlaudio,\n    sound,\n    utils,\n    webaudio,\n};\n"],"names":["instance","setInstance","sound","getInstance","destination","source","_a","Filter","amount","distortion","audioContext","value","scaledValue","samples","curve","deg","i","x","param","context","_EqualizerFilter","f32","f64","f125","f250","f500","f1k","f2k","f4k","f8k","f16k","bands","equalizerBands","band","node","WebAudioUtils","frequency","gain","EqualizerFilter","merger","splitter","h$2","seconds","decay","reverse","min","max","rate","length","impulse","impulseL","impulseR","n","convolver","p$2","pan","stereo","panner","l$4","lpf1","lpf2","hpf1","hpf2","t$1","EventEmitter","_filters","id","_HTMLAudioInstance","parent","name","currentTime","paused","media","speed","volume","loop","muted","global","globalVolume","soundVolume","instanceVolume","pausedReal","options","start","end","Ticker","HTMLAudioInstance","HTMLAudioMedia","callback","onLoad","removeListeners","onAbort","onError","message","complete","extensions","mimes","supported","validateFormats","typeOverrides","overrides","__spreadValues","audio","formats","no","ext","canByExt","canByType","m$2","filters","filter","duration","enabled","force","now","delta","progress","soundLength","err","n$2","input","output","prevFilter","_WebAudioNodes","Filterable","bufferSource","analyser","orig","WebAudioNodes","WebAudioInstance","buffer","url","response","DOMAdapter","arrayBuffer","audioBufferReadyFn","_Sound","WebAudioMedia","urls","file","path","a","b","data","results","alias","sprite","SoundSprite","resolve","reject","len","index","Sound","win","ctx","WebAudioContext","compressor","state","handleError","result","c","l","f","d","s","o","m$1","HTMLAudioContext","filtersAll","sourceOptions","legacy","autoPause","assert","exists","PLAY_ID","playOnce","h","C","v","e","t","g","render","canvas","textureSource","CanvasSource","step","amp","j","datum","sineTone","hertz","nChannels","sampleRate","amplitude","fArray","time","angle","getAlias","asset","src","soundAsset","ExtensionType","exts","LoaderParserPriority","mime","__spreadProps","_b","_sound","SoundLibrary"],"mappings":"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"}