/**
 * Playback-rate controller that keeps audio latency near a target.
 *
 * You feed it the live render-buffer size (`audioRenderBufferMs`, how much audio
 * is currently queued ahead of the speakers, a proxy for latency) and it decides
 * whether playback should speed up, slow down, or run at 1×.
 *
 * It is a hysteresis controller, not a proportional one: it reacts only when the
 * buffer leaves an on-target band, then holds that correction until the buffer
 * has crossed all the way back to the target before returning to 1×. Overshooting
 * to the target (rather than just re-entering the band) avoids oscillating around
 * the edges.
 *
 *   buffer > target·(1 + onTargetPerct)  → speed up, hold until buffer ≤ target
 *   buffer < target·(1 - onTargetPerct)  → slow down, hold until buffer ≥ target
 *   otherwise                            → no change
 *
 * The controller is decision-only: `currentRenderBuffer` returns the new speed to
 * apply (or null when nothing changed) so the caller can forward it to
 * GapTolerantPlayer.setPlaybackSpeed without this class owning the player.
 */
export interface PlaybackRateControllerOptions {
    /** Target latency (ms), i.e. the render-buffer size we steer toward. */
    targetLatencyMs: number;
    /** Half-width of the do-nothing band as a fraction of target, 0 < v < 1. Default 0.2. */
    onTargetPerct?: number;
    /** Rate applied while draining an over-full buffer, 1 < v <= 2. Default 1.05. */
    speedUp?: number;
    /** Rate applied while refilling an under-full buffer, 0.5 <= v < 1. Default 0.95. */
    slowDown?: number;
    onLog?: (msg: string) => void;
}
export declare class PlaybackRateController {
    private targetLatencyMs;
    private onTargetPerct;
    private speedUp;
    private slowDown;
    private onLog?;
    private upperMs;
    private lowerMs;
    private mode;
    constructor(opts: PlaybackRateControllerOptions);
    /**
     * Update any subset of the config at any time (target, band, rates, logger).
     * All provided values are range-checked before anything is applied, so a bad
     * value leaves the controller unchanged. The on-target band is recomputed here
     * (not on every currentRenderBuffer call). The mode is left as-is; a rate
     * change takes audible effect on the next transition.
     */
    updateConfig(opts: Partial<PlaybackRateControllerOptions>): void;
    /** Retarget at any time; the next currentRenderBuffer() call steers to the new value. */
    setTargetLatency(targetLatencyMs: number): void;
    /** Snap back to 1x/normal, e.g. when compensation is toggled off. */
    reset(): void;
    /** The playback speed currently commanded by the controller. */
    getSpeed(): number;
    /**
     * Feed the latest render-buffer size and update the correction. Returns the new
     * playback speed to apply, or null when the command is unchanged (so the caller
     * only touches the player on an actual transition).
     */
    currentRenderBuffer(audioRenderBufferMs: number): number | null;
    private enter;
}
//# sourceMappingURL=playback_rate_controller.d.ts.map