import { TransformOptions, Transform, TransformCallback, Readable } from 'stream';
import { EventEmitter } from 'events';

declare const FilterType: {
    readonly SinglePoleLowPassApprox: 0;
    readonly SinglePoleLowPass: 1;
    readonly LowPass: 2;
    readonly HighPass: 3;
    readonly BandPass: 4;
    readonly Notch: 5;
    readonly AllPass: 6;
    readonly LowShelf: 7;
    readonly HighShelf: 8;
    readonly PeakingEQ: 9;
};
type BiquadFilters = keyof typeof FilterType | (typeof FilterType)[keyof typeof FilterType];
interface CoefficientsInit {
    a1: number;
    a2: number;
    b0: number;
    b1: number;
    b2: number;
}
declare const Q_BUTTERWORTH: number;
declare class Coefficients {
    a1: number;
    a2: number;
    b0: number;
    b1: number;
    b2: number;
    constructor(data?: CoefficientsInit);
    static from(filter: BiquadFilters, samplingFreq: number, cutoffFreq: number, Q: number, dbGain?: number): Coefficients;
}

interface BiquadSetFilterProps {
    f0: number;
    fs: number;
    Q: number;
    gain?: number;
}
declare class BiquadFilter {
    coefficients: Coefficients;
    x1: number;
    x2: number;
    y1: number;
    y2: number;
    s1: number;
    s2: number;
    constructor(coefficients: Coefficients);
    setFilter(filter: BiquadFilters, options: BiquadSetFilterProps): void;
    update(coefficients: Coefficients): void;
    replace(coefficients: Coefficients): void;
    reset(): void;
    run(input: number): number;
    runTransposed(input: number): number;
}

declare class Frequency {
    private __val;
    constructor(__val: number);
    khz(): number;
    mhz(): number;
    hz(): number;
    dt(): number;
    valueOf(): number;
    toString(): string;
    toJSON(): string;
}

type PCMType = `s${16 | 32}${'l' | 'b'}e`;
interface PCMTransformerOptions extends TransformOptions {
    type?: PCMType;
    disabled?: boolean;
    sampleRate?: number;
}
declare class PCMTransformer extends Transform {
    readonly type: PCMType;
    bits: number;
    bytes: number;
    extremum: number;
    disabled: boolean;
    sampleRate: number;
    onUpdate: () => void;
    constructor(options?: PCMTransformerOptions);
    disable(): void;
    enable(): void;
    toggle(): boolean;
    _readInt(buffer: Buffer, index: number): number;
    _writeInt(buffer: Buffer, int: number, index: number): number;
    clamp(val: number, max?: number, min?: number): number;
    setSampleRate(rate: number): void;
}

interface BiquadStreamOptions extends PCMTransformerOptions {
    filter?: BiquadFilters;
    Q?: number;
    cutoff?: number;
    gain?: number;
}
interface BiquadFilterUpdateData {
    filter?: BiquadFilters;
    Q?: number;
    cutoff?: number;
    gain?: number;
}
declare class BiquadStream extends PCMTransformer {
    biquad: BiquadFilter;
    cutoff: number;
    gain: number;
    biquadFilter: BiquadFilters;
    Q: number;
    constructor(options?: BiquadStreamOptions);
    get filters(): BiquadFilters;
    set filters(f: BiquadFilters);
    getFilterName(): BiquadFilters | null;
    update(options: BiquadFilterUpdateData): void;
    setFilter(filter: BiquadFilters): void;
    setQ(Q: number): void;
    setCutoff(f0: number): void;
    setGain(dB: number): void;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
}

type ReadIntCallback = (buffer: Buffer, index: number) => number;
type WriteIntCallback = (buffer: Buffer, int: number, index: number) => number;
declare class ChannelProcessor {
    history: number[];
    bandMultipliers: number[];
    current: number;
    m1: number;
    m2: number;
    constructor(bandMultipliers: number[]);
    processInt(int: number): number;
    process(samples: Buffer, extremum?: number, bytes?: number, readInt?: ReadIntCallback, writeInt?: WriteIntCallback): Buffer;
    step(): void;
    reset(): void;
}

declare class EqualizerCoefficients {
    beta: number;
    alpha: number;
    gamma: number;
    constructor(beta: number, alpha: number, gamma: number);
    setBeta(v: number): void;
    setAlpha(v: number): void;
    setGamma(v: number): void;
    toJSON(): {
        alpha: number;
        beta: number;
        gamma: number;
    };
}

declare class EqualizerConfiguration {
    bandMultipliers: number[];
    constructor(bandMultipliers: number[]);
    setGain(band: number, value: number): void;
    getGain(band: number): number;
    isValidBand(band: number): boolean;
}

interface ChannelProcessorInput {
    data: Buffer;
    readInt?: ReadIntCallback;
    writeInt?: WriteIntCallback;
    extremum?: number;
    bytes?: number;
}
declare class Equalizer extends EqualizerConfiguration {
    static BAND_COUNT: 15;
    static SAMPLE_RATE: 48000;
    static Coefficients48000: EqualizerCoefficients[];
    channels: ChannelProcessor[];
    channelCount: number;
    constructor(channelCount: number, bandMultipliers: number[]);
    createChannelProcessor(): ChannelProcessor[];
    process(input: ChannelProcessorInput[]): Buffer[];
}

interface EqualizerStreamOptions extends PCMTransformerOptions {
    bandMultiplier?: EqualizerBand[];
    channels?: number;
}
interface EqualizerBand {
    band: number;
    gain: number;
}
declare class EqualizerStream extends PCMTransformer {
    bandMultipliers: number[];
    equalizer: Equalizer;
    constructor(options?: EqualizerStreamOptions);
    _processBands(multiplier: EqualizerBand[]): void;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
    getEQ(): EqualizerBand[];
    setEQ(bands: EqualizerBand[]): void;
    resetEQ(): void;
}

type MSTStrategy = 'm2s' | 's2m';
interface MonoStereoTransformerOptions extends PCMTransformerOptions {
    strategy: MSTStrategy;
}
declare class MonoStereoTransformer extends PCMTransformer {
    strategy: MSTStrategy;
    constructor(options?: MonoStereoTransformerOptions);
    setStrategy(strategy: MSTStrategy): void;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
    toStereo(sample: Buffer, len: number): Buffer;
    toMono(sample: Buffer, len: number): Buffer;
}

interface AFBiquadConfig {
    biquad: BiquadFilter;
    sample: number;
    cutoff: number;
    gain: number;
    filter: BiquadFilters;
    coefficient: Coefficients;
    Q: number;
}
declare function applyBiquad(filterer: BiquadFilter, int: number): number;

interface AFPulsatorConfig {
    hz: number;
    x: number;
    dI: number;
}
interface AFTremoloConfig {
    phase: number;
    depth: number;
    frequency: number;
}
type AFVibratoConfig = AFTremoloConfig;
type LR = 0 | 1;
declare function applyPulsator(config: AFPulsatorConfig, int: number, channel: LR): number;
declare function applyTremolo(config: AFTremoloConfig, int: number, sampleRate: number): number;
declare function applyVibrato(config: AFVibratoConfig, int: number, sampleRate: number): number;
declare function applyVolume(vol: number, int: number): number;

declare function applyEqualization(eq: Equalizer, int: number): number;

type index_AFBiquadConfig = AFBiquadConfig;
type index_AFPulsatorConfig = AFPulsatorConfig;
type index_AFTremoloConfig = AFTremoloConfig;
type index_AFVibratoConfig = AFVibratoConfig;
type index_LR = LR;
declare const index_applyBiquad: typeof applyBiquad;
declare const index_applyEqualization: typeof applyEqualization;
declare const index_applyPulsator: typeof applyPulsator;
declare const index_applyTremolo: typeof applyTremolo;
declare const index_applyVibrato: typeof applyVibrato;
declare const index_applyVolume: typeof applyVolume;
declare namespace index {
  export { type index_AFBiquadConfig as AFBiquadConfig, type index_AFPulsatorConfig as AFPulsatorConfig, type index_AFTremoloConfig as AFTremoloConfig, type index_AFVibratoConfig as AFVibratoConfig, type index_LR as LR, index_applyBiquad as applyBiquad, index_applyEqualization as applyEqualization, index_applyPulsator as applyPulsator, index_applyTremolo as applyTremolo, index_applyVibrato as applyVibrato, index_applyVolume as applyVolume };
}

declare const AudioFilters: {
    readonly '8D': "8D";
    readonly Tremolo: "Tremolo";
    readonly Vibrato: "Vibrato";
};
type PCMFilters = keyof typeof AudioFilters;
interface PCMFiltererOptions extends PCMTransformerOptions {
    filters?: PCMFilters[];
}
declare const AF_NIGHTCORE_RATE: 1.3;
declare const AF_VAPORWAVE_RATE: 0.8;
declare const BASS_EQ_BANDS: EqualizerBand[];
declare class AudioFilter extends PCMTransformer {
    filters: PCMFilters[];
    targetSampleRate: number;
    pulsatorConfig: AFPulsatorConfig;
    tremoloConfig: AFTremoloConfig;
    vibratoConfig: AFVibratoConfig;
    constructor(options?: PCMFiltererOptions);
    setTargetSampleRate(rate: number): void;
    setPulsator(hz: number): void;
    get pulsator(): number;
    setTremolo({ depth, frequency, phase, }: Partial<AFTremoloConfig>): void;
    setVibrato({ depth, frequency, phase, }: Partial<AFVibratoConfig>): void;
    get tremolo(): AFTremoloConfig;
    setFilters(filters: PCMFilters[]): boolean;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
    get currentSampleRate(): number;
    applyFilters(byte: number, channel: LR): number;
}

interface PCMResamplerOptions extends PCMTransformerOptions {
    inputSampleRate: number;
    targetSampleRate: number;
    channels?: number;
}
interface ResampleParameters {
    currentFilter: CommonResamplerFilterPreset | null;
    inputSampleRate: number;
    channels: number;
    sampleRate: number;
}
type CommonResamplerFilterPreset = 'nightcore' | 'vaporwave';
declare class PCMResampler extends PCMTransformer {
    private readonly inputSampleRate;
    private readonly channels;
    private buffer;
    currentFilter: CommonResamplerFilterPreset | null;
    constructor(options?: PCMResamplerOptions);
    setFilter(filter: CommonResamplerFilterPreset | null): void;
    getParameters(): ResampleParameters;
    toggleFilter(filter: CommonResamplerFilterPreset): boolean;
    getRatio(): number;
    private resample;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null, data?: Buffer) => void): void;
    _flush(callback: (error?: Error | null, data?: Buffer) => void): void;
    setSampleRate(rate: number): void;
}

interface VolumeTransformerOptions extends PCMTransformerOptions {
    volume?: number;
}
declare class VolumeTransformer extends PCMTransformer {
    private _volume;
    constructor(options?: VolumeTransformerOptions);
    get volumeApprox(): number;
    get volume(): number;
    set volume(volume: number);
    setVolume(volume: number): boolean;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
    toString(): string;
}

interface CompressorOptions extends PCMTransformerOptions {
    threshold?: number;
    ratio?: number;
    attack?: number;
    release?: number;
    makeupGain?: number;
    kneeWidth?: number;
}
interface CompressorParameters {
    threshold: number;
    ratio: number;
    attack: number;
    release: number;
    makeupGain: number;
    kneeWidth: number;
}
declare class CompressorTransformer extends PCMTransformer {
    private threshold;
    private ratio;
    private attack;
    private release;
    private makeupGain;
    private kneeWidth;
    private envelope;
    private gainReduction;
    private previousGainReduction;
    constructor(options?: CompressorOptions);
    private linearToDb;
    private dbToLinear;
    setThreshold(db: number): void;
    setRatio(ratio: number): void;
    setAttack(ms: number): void;
    setRelease(ms: number): void;
    setMakeupGain(db: number): void;
    setKneeWidth(db: number): void;
    setCompressor(options: Partial<CompressorParameters>): CompressorParameters;
    getParameters(): CompressorParameters;
    private computeGainReduction;
    private processSample;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null, data?: Buffer) => void): void;
}

interface PCMSeekerOptions extends PCMTransformerOptions {
    totalDuration: number;
    channels: number;
    seekTarget?: number | null;
}
interface SeekerParameters {
    currentPosition: number;
    seekTarget: number | null;
    totalDuration: number;
}
interface SeekEvent {
    position: number;
    sample: number;
    bytePosition: number;
}
declare class PCMSeekerTransformer extends PCMTransformer {
    private totalDuration;
    private readonly channels;
    private bytesPerFrame;
    private currentPosition;
    private seekTarget;
    private buffer;
    readonly events: EventEmitter<[never]>;
    constructor(options?: PCMSeekerOptions);
    getParameters(): SeekerParameters;
    private updateDependentValues;
    /**
     * Calculate byte position from sample position
     * @param samplePosition Position in samples
     * @returns Position in bytes
     */
    private sampleToBytePosition;
    setTotalDuration(duration: number): void;
    setSampleRate(rate: number): void;
    /**
     * Seek to a specific position in milliseconds
     * @param ms Position in milliseconds (negative values seek from end)
     * @returns Actual position in milliseconds after seeking
     */
    seek(ms: number): number;
    getPosition(): number;
    private handleSeek;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null, data?: Buffer) => void): void;
    _flush(callback: (error?: Error | null, data?: Buffer) => void): void;
}

interface ReverbOptions extends PCMTransformerOptions {
    roomSize?: number;
    damping?: number;
    wetLevel?: number;
    dryLevel?: number;
}
interface ReverbParameters {
    roomSize: number;
    damping: number;
    wetLevel: number;
    dryLevel: number;
}
declare class ReverbTransformer extends PCMTransformer {
    private roomSize;
    private damping;
    private wetLevel;
    private dryLevel;
    private readonly delayLines;
    private readonly delayLineLength;
    private delayIndices;
    private readonly numDelayLines;
    private readonly feedback;
    constructor(options?: ReverbOptions);
    setRoomSize(size: number): void;
    setDamping(damping: number): void;
    setWetLevel(level: number): void;
    setDryLevel(level: number): void;
    setReverb(options: Partial<ReverbParameters>): ReverbParameters;
    getParameters(): ReverbParameters;
    private processSample;
    _transform(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null, data?: Buffer) => void): void;
}

interface DSPFiltersPreset {
    equalizer?: EqualizerStreamOptions;
    dsp?: PCMFiltererOptions;
    biquad?: BiquadStreamOptions;
    volume?: VolumeTransformerOptions;
    resampler?: PCMResamplerOptions;
    compressor?: CompressorOptions;
    seeker?: PCMSeekerOptions;
    reverb?: ReverbOptions;
}
declare class FiltersChain {
    presets: DSPFiltersPreset;
    equalizer: EqualizerStream | null;
    filters: AudioFilter | null;
    biquad: BiquadStream | null;
    volume: VolumeTransformer | null;
    resampler: PCMResampler | null;
    compressor: CompressorTransformer | null;
    seeker: PCMSeekerTransformer | null;
    reverb: ReverbTransformer | null;
    destination: Readable | null;
    source: Readable | null;
    onUpdate: () => unknown;
    onError: (err: Error) => unknown;
    constructor(presets?: DSPFiltersPreset);
    create(src: Readable, presets?: DSPFiltersPreset): Readable;
    destroy(): void;
}

declare const version: string;

export { AF_NIGHTCORE_RATE, AF_VAPORWAVE_RATE, AudioFilter, AudioFilters, BASS_EQ_BANDS, BiquadFilter, type BiquadFilterUpdateData, type BiquadFilters, type BiquadSetFilterProps, BiquadStream, type BiquadStreamOptions, ChannelProcessor, type ChannelProcessorInput, Coefficients, type CommonResamplerFilterPreset, type CompressorOptions, type CompressorParameters, CompressorTransformer, type DSPFiltersPreset, Equalizer, type EqualizerBand, EqualizerCoefficients, EqualizerConfiguration, EqualizerStream, type EqualizerStreamOptions, FilterType, FiltersChain, Frequency, type MSTStrategy, MonoStereoTransformer, type MonoStereoTransformerOptions, index as PCMAudioTransformer, type PCMFiltererOptions, type PCMFilters, PCMResampler, type PCMResamplerOptions, type PCMSeekerOptions, PCMSeekerTransformer, PCMTransformer, type PCMTransformerOptions, type PCMType, Q_BUTTERWORTH, type ReadIntCallback, type ResampleParameters, type ReverbOptions, type ReverbParameters, ReverbTransformer, type SeekEvent, type SeekerParameters, VolumeTransformer, type VolumeTransformerOptions, type WriteIntCallback, version };
