import { Utils } from '@nativescript/core';
import { AudioParamBase, BaseAudioContext, context_, looksLikePath, makeStubParamHooks, native_, nativeCtor_, normalizeSourcePath, resolveLatencyHint, resolvePannerOptions, toUint8Array } from './common';
let _androidAnalyserStubWarned = false;
function makeAndroidHooks(native) {
    return {
        nativeSet(v) {
            native.setValue(v);
        },
        nativeScheduleSet(v, t) {
            native.setValueAtTime(v, t);
        },
        nativeScheduleLinearRamp(v, t) {
            native.linearRampToValueAtTime(v, t);
        },
        nativeCancel(t) {
            native.cancelScheduledValues(t);
        },
        nativeCancelAndHold(v, t) {
            native.cancelAndHoldAtTime(v, t);
        },
        nativeGetValue() {
            return native.getValue();
        },
        nativeSetAutomationRate(rate) {
            native.setAutomationRate(rate);
        },
    };
}
export class AudioParam extends AudioParamBase {
    constructor(a, b) {
        if (a !== nativeCtor_ || !b) {
            throw new TypeError('Illegal constructor.');
        }
        super(makeAndroidHooks(b), b.getValue());
        this[native_] = b;
    }
    get native() {
        return this[native_];
    }
    getValuesForRange(startTime, sampleRate, frameCount) {
        const range = this.native.getValuesForRange(startTime, sampleRate, frameCount);
        if (!range)
            return [];
        return Utils.dataDeserialize(range);
    }
}
export class AudioNode {
    constructor(context) {
        if (!(context instanceof BaseAudioContext)) {
            throw new TypeError(`${this.constructor.name} constructor: Argument 1 does not implement interface BaseAudioContext.`);
        }
        this[context_] = context;
    }
    get context() {
        return this[context_];
    }
    connect(node, output, input) {
        const that = this;
        const target = node?.native || node;
        try {
            if (typeof output === 'number' && typeof input === 'number')
                that.native.connect(target, output, input);
            else if (typeof output === 'number')
                that.native.connect(target, output);
            else
                that.native.connect(target);
        }
        catch (e) { }
    }
    disconnect(destinationOrOutput, output, input) {
        const that = this;
        try {
            if (!destinationOrOutput) {
                that.native.disconnect();
                return;
            }
            if (typeof destinationOrOutput === 'number') {
                try {
                    that.native.disconnectOutput(destinationOrOutput);
                }
                catch (e) {
                    that.native.disconnect();
                }
                return;
            }
            const dest = destinationOrOutput.native || destinationOrOutput;
            try {
                if (typeof output === 'number' && typeof input === 'number')
                    that.native.disconnectTo(dest, output, input);
                else if (typeof output === 'number')
                    that.native.disconnectTo(dest, output);
                else
                    that.native.disconnectTo(dest);
            }
            catch (e) {
                try {
                    that.native.disconnect();
                }
                catch (ee) { }
            }
        }
        catch (e) { }
    }
}
export class AudioBuffer {
    constructor(options, nativeBuffer) {
        if (!options)
            throw new TypeError('AudioBuffer constructor requires options');
        if (options === nativeCtor_ && nativeBuffer) {
            this[native_] = nativeBuffer;
            return;
        }
        const opts = options;
        const length = Math.max(0, opts.length | 0);
        const ch = opts.numberOfChannels != null ? Math.max(1, opts.numberOfChannels | 0) : 1;
        const sr = opts.sampleRate != null ? opts.sampleRate | 0 : 48000;
        this[native_] = new org.nativescript.audiocontext.AudioBuffer(length, ch, sr);
    }
    get native() {
        return this[native_];
    }
    get sampleRate() {
        return this.native.getSampleRate();
    }
    get length() {
        return this.native.getLength();
    }
    get duration() {
        return this.native.getDuration();
    }
    get numberOfChannels() {
        return this.native.getNumberOfChannels();
    }
    getChannelData(channel) {
        const data = this.native.getChannelData(channel);
        if (!data)
            return null;
        return new Float32Array(ArrayBuffer.from(data));
    }
    copyFromChannel(dest, channel, startInChannel = 0) {
        if (!dest)
            return;
        this.native.copyFromChannel(dest, channel, startInChannel ?? 0);
    }
    copyToChannel(source, channel, startInChannel = 0) {
        if (!source)
            return;
        this.native.copyToChannel(source, channel, startInChannel ?? 0);
    }
}
export class GainNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this._gainParam = null;
        const gain = AudioContext.getInstance().createGain(context.native);
        if (typeof options?.gain === 'number' && options.gain !== 1.0) {
            gain.setValue(options.gain);
        }
        this[native_] = gain;
    }
    get native() {
        return this[native_];
    }
    get gain() {
        if (!this._gainParam)
            this._gainParam = new AudioParam(nativeCtor_, this.native.getGain());
        return this._gainParam;
    }
}
export class AudioDestinationNode extends AudioNode {
    constructor(context, node) {
        super(context);
        this[native_] = node;
    }
    get native() {
        return this[native_];
    }
}
export class BiquadFilterNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this._frequencyParam = null;
        this._qParam = null;
        this._gainParam = null;
        this._detuneParam = null;
        const initialFreq = typeof options.frequency === 'number' ? options.frequency : 350;
        const initialQ = typeof options.Q === 'number' ? options.Q : 1.0;
        const initialGain = typeof options.gain === 'number' ? options.gain : 0.0;
        this[native_] = AudioContext.getInstance().createBiquad(context.native, options.type ?? 'lowpass', initialFreq, initialQ, initialGain);
    }
    get native() {
        return this[native_];
    }
    get frequency() {
        if (!this._frequencyParam)
            this._frequencyParam = new AudioParam(nativeCtor_, this.native.getFrequency());
        return this._frequencyParam;
    }
    get Q() {
        if (!this._qParam)
            this._qParam = new AudioParam(nativeCtor_, this.native.getQ());
        return this._qParam;
    }
    get gain() {
        if (!this._gainParam)
            this._gainParam = new AudioParam(nativeCtor_, this.native.getGain());
        return this._gainParam;
    }
    get detune() {
        if (!this._detuneParam)
            this._detuneParam = new AudioParam(nativeCtor_, this.native.getDetune());
        return this._detuneParam;
    }
}
export class PannerNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        const p = resolvePannerOptions(options);
        const node = AudioContext.getInstance().createPanner(context.native);
        this[native_] = node;
        AudioContext.getInstance().setPannerParams(node, p.positionX, p.positionY, p.positionZ, p.orientationX, p.orientationY, p.orientationZ, p.pan, p.distanceModel, p.panningModel, p.refDistance, p.maxDistance, p.rolloffFactor, p.coneInnerAngle, p.coneOuterAngle, p.coneOuterGain);
    }
    get native() {
        return this[native_];
    }
    get positionX() {
        return this._positionX || (this._positionX = new AudioParam(nativeCtor_, this.native.getPositionXParam()));
    }
    get positionY() {
        return this._positionY || (this._positionY = new AudioParam(nativeCtor_, this.native.getPositionYParam()));
    }
    get positionZ() {
        return this._positionZ || (this._positionZ = new AudioParam(nativeCtor_, this.native.getPositionZParam()));
    }
    get orientationX() {
        return this._orientationX || (this._orientationX = new AudioParam(nativeCtor_, this.native.getOrientationXParam()));
    }
    get orientationY() {
        return this._orientationY || (this._orientationY = new AudioParam(nativeCtor_, this.native.getOrientationYParam()));
    }
    get orientationZ() {
        return this._orientationZ || (this._orientationZ = new AudioParam(nativeCtor_, this.native.getOrientationZParam()));
    }
    get distanceModel() {
        return this.native.getDistanceModel();
    }
    set distanceModel(v) {
        this.native.setDistanceModel(v);
    }
    get panningModel() {
        return this.native.getPanningModel();
    }
    set panningModel(v) {
        this.native.setPanningModel(v);
    }
    get refDistance() {
        return this.native.getRefDistance();
    }
    set refDistance(v) {
        this.native.setRefDistance(v);
    }
    get maxDistance() {
        return this.native.getMaxDistance();
    }
    set maxDistance(v) {
        this.native.setMaxDistance(v);
    }
    get rolloffFactor() {
        return this.native.getRolloffFactor();
    }
    set rolloffFactor(v) {
        this.native.setRolloffFactor(v);
    }
    get coneInnerAngle() {
        return this.native.getConeInnerAngle();
    }
    set coneInnerAngle(v) {
        this.native.setConeInnerAngle(v);
    }
    get coneOuterAngle() {
        return this.native.getConeOuterAngle();
    }
    set coneOuterAngle(v) {
        this.native.setConeOuterAngle(v);
    }
    get coneOuterGain() {
        return this.native.getConeOuterGain();
    }
    set coneOuterGain(v) {
        this.native.setConeOuterGain(v);
    }
    setPosition(x, y, z) {
        this.native.setPosition(x, y, z);
    }
    setOrientation(x, y, z) {
        this.native.setOrientation(x, y, z);
    }
}
export class AudioScheduledSourceNode extends AudioNode {
    constructor(context, node) {
        super(context);
        if (!(node instanceof org.nativescript.audiocontext.AudioScheduledSourceNode))
            throw new TypeError('Illegal constructor.');
        this[native_] = node;
    }
    get native() {
        return this[native_];
    }
    start() {
        this.native.start();
    }
    stop() {
        this.native.stop();
    }
}
export class AudioBufferSourceNode extends AudioScheduledSourceNode {
    constructor(context, options = {}) {
        super(context, AudioContext.getInstance().createBufferSource(context.native, options?.buffer?.native ?? null));
    }
    get native() {
        return this[native_];
    }
    get loop() {
        return this.native.getLoop();
    }
    set loop(v) {
        this.native.setLoop(v);
    }
    get buffer() {
        const b = this.native.getBuffer();
        return b ? new AudioBuffer(nativeCtor_, b) : null;
    }
    set buffer(v) {
        this.native.setBuffer(v?.native ?? null);
    }
}
export class OfflineAudioContext extends BaseAudioContext {
    static getInstance() {
        if (!audioContextInstance)
            audioContextInstance = org.nativescript.audiocontext.AudioContext.getInstance();
        return audioContextInstance;
    }
    constructor(numberOfChannels, lengthInFrames, sampleRate) {
        super();
        this.destination = null;
        this._frames = 0;
        this._sampleRate = 48000;
        this._channels = 1;
        this._frames = Math.max(0, lengthInFrames | 0);
        this._sampleRate = sampleRate && Number.isFinite(sampleRate) ? sampleRate : 48000;
        this._channels = Math.max(1, numberOfChannels | 0);
        this[native_] = OfflineAudioContext.getInstance().createContextInstance();
        this.destination = new AudioDestinationNode(this, this[native_].getDestination());
    }
    get native() {
        return this[native_];
    }
    configure(numberOfChannels, lengthInFrames, sampleRate) {
        this._channels = Math.max(1, numberOfChannels | 0);
        this._frames = Math.max(0, lengthInFrames | 0);
        this._sampleRate = sampleRate && Number.isFinite(sampleRate) ? sampleRate : this._sampleRate;
    }
    createGain(options) {
        return new GainNode(this, options ?? {});
    }
    createBiquad(options) {
        return new BiquadFilterNode(this, options ?? {});
    }
    createPanner(options) {
        return new PannerNode(this, options ?? {});
    }
    createOscillator(options) {
        return new OscillatorNode(this, options ?? {});
    }
    createStereoPanner(options) {
        return new StereoPannerNode(this, options ?? {});
    }
    createDelay(options) {
        return new DelayNode(this, options ?? {});
    }
    createConstantSource(options) {
        return new ConstantSourceNode(this, options ?? {});
    }
    createAnalyser(options) {
        return new AnalyserNode(this, options ?? {});
    }
    createWaveShaper(options) {
        return new WaveShaperNode(this, options ?? {});
    }
    createIIRFilter(feedforward, feedback) {
        return new IIRFilterNode(this, { feedforward, feedback });
    }
    createConvolver(options) {
        return new ConvolverNode(this, options ?? {});
    }
    createPeriodicWave(real, imag, options) {
        return new PeriodicWave(this, { real, imag, disableNormalization: options?.disableNormalization });
    }
    createBufferSource() {
        return new AudioBufferSourceNode(this);
    }
    decodeAudioData(source) {
        return new Promise((resolve, reject) => {
            if (typeof source === 'string') {
                if (looksLikePath(source)) {
                    const filePath = normalizeSourcePath(source);
                    OfflineAudioContext.getInstance().decodeAudioDataFromFileAsync(filePath, this.native, new org.nativescript.audiocontext.DecodeCallback({
                        onResult(buffer) {
                            if (!buffer)
                                return reject(new Error('decodeAudioData failed'));
                            resolve(new AudioBuffer(nativeCtor_, buffer));
                        },
                    }));
                    return;
                }
                OfflineAudioContext.getInstance().decodeAudioDataAsync(source, this.native, new org.nativescript.audiocontext.DecodeCallback({
                    onResult(buffer) {
                        if (!buffer)
                            return reject(new Error('decodeAudioData failed'));
                        resolve(new AudioBuffer(nativeCtor_, buffer));
                    },
                }));
                return;
            }
            const u8 = toUint8Array(source);
            OfflineAudioContext.getInstance().decodeAudioDataFromBufferAsync(u8, this.native, new org.nativescript.audiocontext.DecodeCallback({
                onResult(buffer) {
                    if (!buffer)
                        return reject(new Error('decodeAudioData failed'));
                    resolve(new AudioBuffer(nativeCtor_, buffer));
                },
            }));
        });
    }
    startRendering() {
        return new Promise((resolve, reject) => {
            this.native.renderOfflineAsync(this._frames, this._sampleRate, this._channels, new org.nativescript.audiocontext.DecodeCallback({
                onResult(buffer) {
                    if (!buffer)
                        return reject(new Error('startRendering failed'));
                    resolve(new AudioBuffer(nativeCtor_, buffer));
                },
            }));
        });
    }
}
let audioContextInstance = null;
export class AudioContext extends BaseAudioContext {
    static getInstance() {
        if (!audioContextInstance)
            audioContextInstance = org.nativescript.audiocontext.AudioContext.getInstance();
        return audioContextInstance;
    }
    constructor(options) {
        super();
        this.destination = null;
        this._sinkId = 'default';
        audioContextInstance = org.nativescript.audiocontext.AudioContext.getInstance();
        const sampleRate = options?.sampleRate ?? 0;
        const latencyHintSec = resolveLatencyHint(options?.latencyHint);
        this[native_] = audioContextInstance.createContextInstance(sampleRate, latencyHintSec);
        this.destination = new AudioDestinationNode(this, this[native_].getDestination());
    }
    get native() {
        return this[native_];
    }
    get sampleRate() {
        return this.native.getSampleRate();
    }
    get currentTime() {
        return this.native.getCurrentTime();
    }
    createGain(options) {
        return new GainNode(this, options ?? {});
    }
    createBiquad(options) {
        return new BiquadFilterNode(this, options ?? {});
    }
    createPanner(options) {
        return new PannerNode(this, options ?? {});
    }
    createOscillator(options) {
        return new OscillatorNode(this, options ?? {});
    }
    createStereoPanner(options) {
        return new StereoPannerNode(this, options ?? {});
    }
    createDelay(options) {
        return new DelayNode(this, options ?? {});
    }
    createConstantSource(options) {
        return new ConstantSourceNode(this, options ?? {});
    }
    createAnalyser(options) {
        return new AnalyserNode(this, options ?? {});
    }
    createWaveShaper(options) {
        return new WaveShaperNode(this, options ?? {});
    }
    createIIRFilter(feedforward, feedback) {
        return new IIRFilterNode(this, { feedforward, feedback });
    }
    createConvolver(options) {
        return new ConvolverNode(this, options ?? {});
    }
    createPeriodicWave(real, imag, options) {
        return new PeriodicWave(this, { real, imag, disableNormalization: options?.disableNormalization });
    }
    createBuffer(options) {
        return new AudioBuffer(options);
    }
    createBufferSource(options) {
        return new AudioBufferSourceNode(this, options);
    }
    renderOffline(trackIds, frames, sampleRate, channels) {
        return new Promise((resolve, reject) => {
            AudioContext.getInstance().renderOfflineAsync(trackIds, frames, sampleRate, channels, new org.nativescript.audiocontext.DecodeCallback({
                onResult(buffer) {
                    if (!buffer)
                        return reject(new Error('renderOffline failed'));
                    resolve(new AudioBuffer(nativeCtor_, buffer));
                },
            }));
        });
    }
    async decodeAudioData(source) {
        return new Promise((resolve, reject) => {
            if (typeof source === 'string') {
                if (looksLikePath(source)) {
                    const filePath = normalizeSourcePath(source);
                    AudioContext.getInstance().decodeAudioDataFromFileAsync(filePath, this.native, new org.nativescript.audiocontext.DecodeCallback({
                        onResult(buffer) {
                            if (!buffer)
                                return reject(new Error('decodeAudioData failed'));
                            resolve(new AudioBuffer(nativeCtor_, buffer));
                        },
                    }));
                    return;
                }
                AudioContext.getInstance().decodeAudioDataAsync(source, this.native, new org.nativescript.audiocontext.DecodeCallback({
                    onResult(buffer) {
                        if (!buffer)
                            return reject(new Error('decodeAudioData failed'));
                        resolve(new AudioBuffer(nativeCtor_, buffer));
                    },
                }));
                return;
            }
            const u8 = toUint8Array(source);
            AudioContext.getInstance().decodeAudioDataFromBufferAsync(u8, this.native, new org.nativescript.audiocontext.DecodeCallback({
                onResult(buffer) {
                    if (!buffer)
                        return reject(new Error('decodeAudioData failed'));
                    resolve(new AudioBuffer(nativeCtor_, buffer));
                },
            }));
        });
    }
    resume() {
        AudioContext.getInstance().resume();
        return Promise.resolve();
    }
    suspend() {
        AudioContext.getInstance().suspend();
        return Promise.resolve();
    }
    close() {
        if (this.native) {
            this.native.release();
        }
        this.destination = null;
        return Promise.resolve();
    }
    get sinkId() {
        return this._sinkId;
    }
    setSinkId(deviceId) {
        return new Promise((resolve, reject) => {
            try {
                const value = deviceId == null || deviceId === '' ? 'default' : String(deviceId);
                const ok = this.native.setSinkId(value);
                if (ok) {
                    this._sinkId = value;
                    resolve();
                }
                else {
                    reject(new Error(`setSinkId(${deviceId}) rejected by native engine`));
                }
            }
            catch (e) {
                reject(e);
            }
        });
    }
}
export class OscillatorNode extends AudioScheduledSourceNode {
    constructor(context, options = {}) {
        const type = options?.type || 'sine';
        const freq = options?.frequency || 440;
        super(context, context.native.createOscillatorNodeFrequency(type, freq));
        this._periodicWave = null;
    }
    get native() {
        return this[native_];
    }
    get frequency() {
        if (!this._frequencyParam)
            this._frequencyParam = new AudioParam(nativeCtor_, this.native.getFrequency());
        return this._frequencyParam;
    }
    setPeriodicWave(wave) {
        if (!wave)
            return;
        this._periodicWave = wave;
        this.native.setPeriodicWave(wave.native);
    }
}
class StubAudioParam extends AudioParamBase {
    constructor(initial = 0) {
        const hooks = makeStubParamHooks();
        super(hooks, initial);
        if (initial !== 0)
            hooks.nativeSet(initial);
    }
}
export class StereoPannerNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this._panParam = null;
        const p = resolvePannerOptions({ pan: options.pan });
        const node = AudioContext.getInstance().createPanner(context.native);
        this[native_] = node;
        AudioContext.getInstance().setPannerParams(node, p.positionX, p.positionY, p.positionZ, p.orientationX, p.orientationY, p.orientationZ, p.pan, p.distanceModel, p.panningModel, p.refDistance, p.maxDistance, p.rolloffFactor, p.coneInnerAngle, p.coneOuterAngle, p.coneOuterGain);
    }
    get native() {
        return this[native_];
    }
    get pan() {
        if (!this._panParam) {
            this._panParam = new AudioParam(nativeCtor_, this.native.getPan());
        }
        return this._panParam;
    }
}
export class DelayNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this._delayTimeParam = null;
        this.maxDelayTime = typeof options.maxDelayTime === 'number' ? options.maxDelayTime : 1.0;
        const delay = AudioContext.getInstance().createDelay(context.native);
        if (typeof options.delayTime === 'number' && options.delayTime !== 0) {
            delay.getDelayTime().setValue(options.delayTime);
        }
        this[native_] = delay;
    }
    get native() {
        return this[native_];
    }
    get delayTime() {
        if (!this._delayTimeParam) {
            const param = this.native.getDelayTime();
            this._delayTimeParam = new AudioParam(nativeCtor_, param);
        }
        return this._delayTimeParam;
    }
}
export class ConstantSourceNode extends AudioScheduledSourceNode {
    constructor(context, options = {}) {
        const node = AudioContext.getInstance().createConstantSource(context.native);
        super(context, node);
        this._offsetParam = null;
        if (typeof options.offset === 'number') {
            node.getOffsetParam().setValue(options.offset);
        }
    }
    get native() {
        return this[native_];
    }
    get offset() {
        if (!this._offsetParam) {
            this._offsetParam = new AudioParam(nativeCtor_, this.native.getOffsetParam());
        }
        return this._offsetParam;
    }
}
export class AnalyserNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this[native_] = AudioContext.getInstance().createAnalyser(context.native);
        if (typeof options.fftSize === 'number')
            this.native.setFftSize(options.fftSize | 0);
        if (typeof options.smoothingTimeConstant === 'number')
            this.native.setSmoothingTimeConstant(options.smoothingTimeConstant);
        if (typeof options.minDecibels === 'number')
            this.native.setMinDecibels(options.minDecibels);
        if (typeof options.maxDecibels === 'number')
            this.native.setMaxDecibels(options.maxDecibels);
    }
    get native() {
        return this[native_];
    }
    get fftSize() {
        return this.native.getFftSize();
    }
    set fftSize(v) {
        this.native.setFftSize(v | 0);
    }
    get frequencyBinCount() {
        return (this.native.getFftSize() / 2) | 0;
    }
    get smoothingTimeConstant() {
        return this.native.getSmoothingTimeConstant();
    }
    set smoothingTimeConstant(v) {
        this.native.setSmoothingTimeConstant(v);
    }
    get minDecibels() {
        return this.native.getMinDecibels();
    }
    set minDecibels(v) {
        this.native.setMinDecibels(v);
    }
    get maxDecibels() {
        return this.native.getMaxDecibels();
    }
    set maxDecibels(v) {
        this.native.setMaxDecibels(v);
    }
    getFloatTimeDomainData(dest) {
        if (!dest || dest.length === 0)
            return;
        this.native.getFloatTimeDomainData(dest);
    }
    getByteTimeDomainData(dest) {
        if (!dest || dest.length === 0)
            return;
        this.native.getByteTimeDomainData(dest);
    }
    getFloatFrequencyData(dest) {
        if (!dest || dest.length === 0)
            return;
        this.native.getFloatFrequencyData(dest);
    }
    getByteFrequencyData(dest) {
        if (!dest || dest.length === 0)
            return;
        this.native.getByteFrequencyData(dest);
    }
}
export class WaveShaperNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this._curve = null;
        this[native_] = AudioContext.getInstance().createWaveShaper(context.native);
        if (options.curve)
            this.curve = options.curve instanceof Float32Array ? options.curve : Float32Array.from(options.curve);
        if (options.oversample)
            this.oversample = options.oversample;
    }
    get native() {
        return this[native_];
    }
    get curve() {
        return this._curve;
    }
    set curve(v) {
        this._curve = v;
        this.native.setCurveFromData(v ?? null);
    }
    get oversample() {
        return this.native.getOversample();
    }
    set oversample(v) {
        this.native.setOversample(v);
    }
}
export class IIRFilterNode extends AudioNode {
    constructor(context, options) {
        super(context);
        if (!options?.feedforward?.length || !options?.feedback?.length)
            throw new TypeError('IIRFilterNode: feedforward and feedback are required');
        this[native_] = AudioContext.getInstance().createIIR(context.native, options.feedforward, options.feedback);
    }
    get native() {
        return this[native_];
    }
    getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {
        if (!frequencyHz || !magResponse || !phaseResponse)
            return;
        this.native.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);
    }
}
export class ConvolverNode extends AudioNode {
    constructor(context, options = {}) {
        super(context);
        this[native_] = AudioContext.getInstance().createConvolver(context.native);
        this.normalize = !options.disableNormalization;
    }
    get native() {
        return this[native_];
    }
    get buffer() {
        const buffer = this.native.getBuffer();
        if (!buffer)
            return null;
        return new AudioBuffer(nativeCtor_, buffer);
    }
    set buffer(value) {
        this.native.setBuffer(value?.native ?? null);
    }
    get normalize() {
        return this.native.getNormalize();
    }
    set normalize(value) {
        this.native.setNormalize(value);
    }
}
export class PeriodicWave {
    constructor(_context, options = {}) {
        this.real = options.real ? (options.real instanceof Float32Array ? options.real : Float32Array.from(options.real)) : new Float32Array(2);
        this.imag = options.imag ? (options.imag instanceof Float32Array ? options.imag : Float32Array.from(options.imag)) : new Float32Array(this.real.length);
        this.disableNormalization = !!options.disableNormalization;
        this[native_] = AudioContext.getInstance().createPeriodicWave(_context.native, this.real, this.imag, this.disableNormalization);
    }
    get native() {
        return this[native_];
    }
}
//# sourceMappingURL=index.android.js.map