/** * Beat detection + cut-snapping primitive. * * `detectBeats` shells out to a librosa-backed sidecar; `snapCuts` is the * pure algorithm that clamps proposed cut points to the nearest detected * beat within a tolerance. The split keeps the algorithm fully unit-testable * (no Python required) and isolates the heavy import-path inside the sidecar. */ export interface DetectBeatsResult { /** Estimated tempo (BPM). */ tempo: number; /** Beat times in seconds, sorted ascending. */ beats: number[]; /** Audio duration in seconds (post-load). */ durationSec: number; } export interface DetectBeatsOptions { signal?: AbortSignal; /** Optional librosa target sample rate. Defaults to librosa's choice (22050). */ sampleRate?: number; } /** * Spawn the beats sidecar, write `{audioPath, sr}` to stdin, return the * parsed JSON. Throws with a structured message on sidecar failure so the * tool wrapper can format it for the agent. */ export declare function detectBeats(audioPath: string, opts?: DetectBeatsOptions): Promise; export interface SnappedCut { /** The cut point as supplied by the caller. */ originalSec: number; /** The beat time it was snapped to. */ snappedSec: number; /** Index into the beats array. */ beatIdx: number; /** Signed offset (snappedSec - originalSec). Magnitude ≤ toleranceSec. */ deltaSec: number; } export interface UnchangedCut { /** Cut point that fell beyond toleranceSec from any beat. */ atSec: number; /** Distance to the closest beat (positive). undefined if no beats supplied. */ nearestBeatDeltaSec?: number; } export interface SnapResult { snapped: SnappedCut[]; unchanged: UnchangedCut[]; } /** * Snap each cut point to the nearest beat within `toleranceSec`. Cuts beyond * the tolerance are returned in `unchanged` with their distance to the * closest beat (so the agent can decide whether to widen the tolerance). * * Tiebreak: when two beats are equidistant, the EARLIER beat wins. (Cuts * read more naturally on the upbeat than the downbeat that follows.) * * Pure function — no I/O. Beats list need not be sorted; we sort defensively. */ export declare function snapCuts(cutPoints: number[], beats: number[], toleranceSec: number): SnapResult; //# sourceMappingURL=beats.d.ts.map