/**
 * Shake detector with frequency-band energy analysis.
 *
 * Maintains circular buffers of per-axis acceleration samples. Shake
 * intensity is computed via RMS of the acceleration magnitude deviation
 * from its mean (high-pass to remove gravity). The dominant shake
 * frequency is identified using the Goertzel algorithm — a single-bin
 * DFT that's far cheaper than a full FFT — applied to the first-
 * difference of individual axis signals:
 *
 *   - Per-axis preserves the fundamental frequency (magnitude would
 *     full-wave-rectify the signal, doubling the apparent frequency).
 *   - First-difference acts as a high-pass filter, removing DC (gravity)
 *     and low-frequency drift from arm movement. Its gain is proportional
 *     to frequency, so the Goertzel output naturally favors oscillatory
 *     shake signals over slow drift — no ad-hoc weighting needed.
 *
 * A 1/freq compensation is applied so the net effective weighting is
 * proportional to freq (diff-filter gain² ∝ freq², divided by freq),
 * giving moderate preference to actual shake frequencies without
 * completely suppressing sub-1 Hz rocking.
 *
 * `.frequency` reports the **reversal rate** (2× fundamental) — how many
 * direction changes per second. This matches the intuitive "how fast am
 * I shaking it?" mental model. `.fundamental` reports the true oscillation
 * frequency (one full back-and-forth cycle).
 *
 * The active flag uses a sustain counter to require several consecutive
 * frames above threshold before triggering, preventing transient jolts
 * from registering as shakes.
 */
/** A single frequency bin with its associated power level. */
export interface FrequencyBin {
    /** Frequency in Hz. */
    freq: number;
    /** Weighted power (arbitrary units, relative within the array). */
    power: number;
}
/** Configuration for the shake detector. */
export interface ShakeDetectorParams {
    /** Intensity (0–1) above which `.active` becomes true. Default 0.15. */
    threshold?: number;
    /** Number of samples in the analysis window. Default 256 (~1s at 250 Hz, ~3s at 84 Hz in browser). */
    windowSize?: number;
    /**
     * Number of consecutive above-threshold frames required before `.active`
     * becomes true. Also the number of below-threshold frames required to
     * deactivate. Default 15 (~60 ms at 250 Hz).
     */
    sustain?: number;
    /** Frequency bin resolution in Hz. Default 0.25. Smaller = finer but more bins to compute. */
    freqStep?: number;
    /** Minimum detectable frequency in Hz. Default 0.25. */
    freqMin?: number;
    /** Maximum detectable frequency in Hz. Default 15. */
    freqMax?: number;
}
export declare class ShakeDetector {
    /** Whether the controller is currently being shaken (sustained). */
    active: boolean;
    /** Shake intensity from 0 (still) to 1 (violent shake). */
    intensity: number;
    /**
     * Dominant shake frequency in Hz as a **reversal rate** — how many
     * direction changes per second (2× the fundamental oscillation
     * frequency). 0 when not shaking.
     */
    frequency: number;
    /**
     * Fundamental oscillation frequency in Hz — one complete back-and-forth
     * cycle. Equal to `frequency / 2`. 0 when not shaking.
     */
    fundamental: number;
    /** Intensity threshold for `active`. */
    threshold: number;
    /** Estimated sample rate in Hz (derived from dt). Useful for diagnostics. */
    get inputRate(): number;
    /** Number of samples in the analysis window. Can be changed at runtime (resets state). */
    get windowSize(): number;
    set windowSize(n: number);
    /**
     * Current frequency spectrum — weighted power at each probed bin.
     * Updated every frame when intensity is above half the threshold.
     * Useful for visualization/diagnostics.
     */
    get spectrum(): readonly FrequencyBin[];
    private bufX;
    private bufY;
    private bufZ;
    private head;
    private filled;
    private _sampleRate;
    /** Sustain counter for debounce — counts up when above threshold, down when below. */
    private sustainCounter;
    private readonly sustainRequired;
    /** EMA-smoothed frequency for stable readout. */
    private smoothedFreq;
    /** Frequency bins to probe, built from constructor params. */
    private readonly freqBins;
    /** Bin step size, used for snapping the EMA output. */
    private readonly freqStep;
    /** Latest computed bin powers. */
    private _bins;
    /**
     * Scale factor: maps RMS of our [-1, 1] calibrated accel deviation
     * to a 0–1 intensity. A vigorous shake produces magnitude-RMS of
     * ~0.3–0.5 in our units; this maps that to ~0.6–1.0 intensity.
     */
    private static readonly INTENSITY_SCALE;
    constructor(params?: ShakeDetectorParams);
    /** Reset all state (call on disconnect). */
    reset(): void;
    /**
     * Feed one accelerometer sample.
     *
     * @param ax  Calibrated accel X ([-1, 1])
     * @param ay  Calibrated accel Y ([-1, 1])
     * @param az  Calibrated accel Z ([-1, 1])
     * @param dt  Time delta in seconds since last sample
     */
    update(ax: number, ay: number, az: number, dt: number): void;
    /**
     * Goertzel algorithm: compute power at a single target frequency.
     *
     * Operates on the first-difference of the filled portion of a circular
     * buffer. The first-difference (x[n] - x[n-1]) acts as a high-pass
     * filter that removes DC (gravity) and low-frequency arm drift, with
     * gain proportional to frequency.
     */
    private goertzel;
}
//# sourceMappingURL=shake.d.ts.map