/** * Structural segmentation of a beat/frame-synchronous feature matrix by * Laplacian spectral clustering (McFee & Ellis, 2014). * * Two input forms: * * - **Single feature stack** — `laplacianSegmentation(features2d, opts)`: * the same d×n matrix drives BOTH the recurrence graph and the path graph. * Convenient when one representation must serve both roles. * * - **Two-feature form** — * `laplacianSegmentation({ recurrenceFeatures, pathFeatures }, opts)`: * the recurrence affinity Rf is built from `recurrenceFeatures` and the * sequential path graph R_path from `pathFeatures` — one feature for * repetition (typically a beat-synced CQT or chroma) and another for * local continuity (typically MFCC). Both matrices must share the same * number of frames (columns); their feature-row counts may differ. * * @param {(number[][]|Float32Array[]|Float64Array[]| * {recurrenceFeatures: number[][], pathFeatures: number[][]})} features * A single d×n feature matrix (rows = features, columns = frames), or an * object carrying separate `recurrenceFeatures` and `pathFeatures` matrices. * @param {Object} [options] * @param {number} [options.k=5] Number of segments / spectral components. * @param {number} [options.width=3] Recurrence-matrix width band (links with * |i − j| < width are suppressed; prevents same-bar self-links). * @param {number} [options.mu=0.5] Balance between recurrence (Rf) and path * (R_path) graphs: `A = μ·Rf + (1 − μ)·R_path`, μ ∈ [0, 1]. * @returns {{ segmentIds: Int32Array, boundaries: number[] }} * `segmentIds[i]` is the cluster label of frame i; `boundaries` is the * ascending list of internal segment-onset frames * (`1 + where(segmentIds[:-1] ≠ segmentIds[1:])`). */ export function laplacianSegmentation(features: (number[][] | Float32Array[] | Float64Array[] | { recurrenceFeatures: number[][]; pathFeatures: number[][]; }), { k, width, mu }?: { k?: number; width?: number; mu?: number; }): { segmentIds: Int32Array; boundaries: number[]; };