import { knownFolders, Observable } from '@nativescript/core';
export const native_ = Symbol('[[native]]');
export const context_ = Symbol('[[context]]');
export const nativeCtor_ = Symbol('[[nativeConstructor]]');
export class BaseAudioContext extends Observable {
}
export function normalizeSourcePath(source) {
    let filePath = source;
    if (filePath.startsWith('~/')) {
        filePath = filePath.replace('~/', knownFolders.currentApp().path + '/');
    }
    if (filePath.startsWith('file://')) {
        filePath = filePath.replace('file://', '');
    }
    return filePath;
}
export function looksLikePath(source) {
    return source.indexOf('/') >= 0 || source.indexOf('file:') === 0 || source.indexOf('~') === 0;
}
export function toUint8Array(source) {
    if (ArrayBuffer.isView(source)) {
        return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
    }
    return new Uint8Array(source);
}
const LATENCY_HINT_SECONDS = {
    interactive: 0.005,
    balanced: 0.012,
    playback: 0.025,
};
export function resolveLatencyHint(hint) {
    if (hint == null)
        return 0;
    if (typeof hint === 'number')
        return Math.max(0, hint);
    return LATENCY_HINT_SECONDS[hint] ?? LATENCY_HINT_SECONDS.balanced;
}
export function resolvePannerOptions(o = {}) {
    return {
        positionX: typeof o.positionX === 'number' ? o.positionX : 0,
        positionY: typeof o.positionY === 'number' ? o.positionY : 0,
        positionZ: typeof o.positionZ === 'number' ? o.positionZ : 0,
        orientationX: typeof o.orientationX === 'number' ? o.orientationX : 1.0,
        orientationY: typeof o.orientationY === 'number' ? o.orientationY : 0.0,
        orientationZ: typeof o.orientationZ === 'number' ? o.orientationZ : 0.0,
        pan: typeof o.pan === 'number' ? o.pan : 0.0,
        distanceModel: typeof o.distanceModel === 'number' ? o.distanceModel : 0,
        panningModel: typeof o.panningModel === 'number' ? o.panningModel : 0,
        refDistance: typeof o.refDistance === 'number' ? o.refDistance : 1.0,
        maxDistance: typeof o.maxDistance === 'number' ? o.maxDistance : 10000.0,
        rolloffFactor: typeof o.rolloffFactor === 'number' ? o.rolloffFactor : 1.0,
        coneInnerAngle: typeof o.coneInnerAngle === 'number' ? o.coneInnerAngle : 360.0,
        coneOuterAngle: typeof o.coneOuterAngle === 'number' ? o.coneOuterAngle : 360.0,
        coneOuterGain: typeof o.coneOuterGain === 'number' ? o.coneOuterGain : 0.0,
    };
}
export function makeStubParamHooks() {
    let current = 0;
    return {
        nativeSet(v) {
            current = v;
        },
        nativeScheduleSet(v) {
            current = v;
        },
        nativeScheduleLinearRamp(v) {
            current = v;
        },
        nativeCancel() { },
        nativeCancelAndHold(v) {
            current = v;
        },
        nativeGetValue() {
            return current;
        },
        nativeSetAutomationRate() { },
    };
}
export class AudioParamBase {
    constructor(hooks, initialValue = 0) {
        this._automationRate = 'a-rate';
        this.hooks = hooks;
        this._cachedValue = initialValue;
    }
    get value() {
        return this._cachedValue;
    }
    set value(v) {
        const nv = +v;
        if (nv === this._cachedValue)
            return;
        this._cachedValue = nv;
        this.hooks.nativeSet(nv);
    }
    _syncFromNative() {
        if (this.hooks.nativeGetValue) {
            const v = this.hooks.nativeGetValue();
            if (Number.isFinite(v))
                this._cachedValue = v;
        }
    }
    get automationRate() {
        return this._automationRate;
    }
    set automationRate(v) {
        this._automationRate = v;
        this.hooks.nativeSetAutomationRate?.(v);
    }
    setValueAtTime(value, time = 0) {
        const nv = +value;
        this._cachedValue = nv;
        this.hooks.nativeScheduleSet(nv, time || 0);
        return this;
    }
    linearRampToValueAtTime(value, time) {
        const nv = +value;
        this._cachedValue = nv;
        this.hooks.nativeScheduleLinearRamp(nv, time);
        return this;
    }
    exponentialRampToValueAtTime(value, time) {
        const nv = +value;
        if (nv <= 0)
            throw new RangeError('exponentialRampToValueAtTime: value must be > 0');
        this._cachedValue = nv;
        if (this.hooks.nativeScheduleExpRamp) {
            this.hooks.nativeScheduleExpRamp(nv, time);
        }
        else {
            this.hooks.nativeScheduleLinearRamp(nv, time);
        }
        return this;
    }
    setTargetAtTime(target, startTime, timeConstant) {
        const nv = +target;
        if (timeConstant < 0)
            throw new RangeError('setTargetAtTime: timeConstant must be >= 0');
        this._cachedValue = nv;
        if (this.hooks.nativeScheduleTarget) {
            this.hooks.nativeScheduleTarget(nv, startTime, timeConstant);
        }
        else {
            const end = startTime + Math.max(0.001, timeConstant * 5);
            this.hooks.nativeScheduleLinearRamp(nv, end);
        }
        return this;
    }
    setValueCurveAtTime(values, startTime, duration) {
        if (!values || values.length < 2) {
            throw new RangeError('setValueCurveAtTime: values must have length >= 2');
        }
        const f32 = values instanceof Float32Array ? values : Float32Array.from(values);
        this._cachedValue = f32[f32.length - 1];
        if (this.hooks.nativeScheduleCurve) {
            this.hooks.nativeScheduleCurve(f32, startTime, duration);
            return this;
        }
        const n = f32.length;
        const step = duration / (n - 1);
        this.hooks.nativeScheduleSet(f32[0], startTime);
        for (let i = 1; i < n; i++) {
            this.hooks.nativeScheduleLinearRamp(f32[i], startTime + step * i);
        }
        return this;
    }
    cancelScheduledValues(time) {
        this.hooks.nativeCancel(time || 0);
        return this;
    }
    cancelAndHoldAtTime(time) {
        const t = time || 0;
        const held = this._cachedValue;
        this.hooks.nativeCancelAndHold(held, t);
        return this;
    }
}
//# sourceMappingURL=common.js.map