/** * Nearest-neighbor filtering (nn_filter). * * Each frame (column) of S is replaced by aggregating its nearest neighbors * in feature space, as selected by recurrence-matrix * semantics: for output frame i the neighbor set is { j : rec[i][j] != 0 }, * via a CSR-row walk in __nn_filter_helper (frames with an empty * neighbor set pass through unchanged). aggregate='median' with a cosine * metric and a width-in-frames exclusion band is the REPET-SIM configuration * (Rafii & Pardo 2012), the standard vocal-separation configuration. * * The recurrence graph itself comes from segment.recurrenceMatrix (Wave-5 * fixture-gated); this function adds only the neighbor-aggregation walk. * NOTE: no direct fixture for the composition yet — behavior is * proven against planted-repetition structure in * examples/web/plot-vocal-separation.html (node-spot-run first). * * @param {Array>} S - Feature matrix [features][frames] * @param {Object} [options] * @param {Array>|null} [options.rec=null] - Precomputed * recurrence matrix [frames][frames]; computed from S * via recurrenceMatrix when null. * @param {string|Function} [options.aggregate='mean'] - 'mean' | 'median' | * 'average' (weighted by rec values) | custom (values, weights) => number. * @param {...*} [options.rest] - Remaining options (metric, width, k, sym, * mode, bandwidth, self, full) forward to recurrenceMatrix. * @returns {Float64Array[]} Filtered matrix, same shape as S * @throws {Error} On empty input, bad rec shape, or unknown aggregate */ export function nn_filter(S: Array>, options?: { rec?: Array> | null; aggregate?: string | Function; rest?: any[]; }): Float64Array[]; /** * Robust soft mask: M = X^power / (X^power + X_ref^power), computed with * a rescale-by-max stabilization. * * @param {Array>} X - Non-negative 2D array [rows][cols] * @param {Array>} X_ref - Reference array, same shape * @param {Object} [options] * @param {number} [options.power=1] - Mask exponent; Infinity gives a hard mask (X > X_ref) * @param {boolean} [options.split_zeros=false] - Give 0.5 (instead of 0) where both inputs underflow * @returns {Float64Array[]} Mask, same shape as X * @throws {Error} On shape mismatch, negative input, or power <= 0 */ export function softmask(X: Array>, X_ref: Array>, { power, split_zeros }?: { power?: number; split_zeros?: boolean; }): Float64Array[]; /** * Median-filtering harmonic/percussive source separation on a spectrogram. * Default behavior: * the default (mask=false) return is the MASKED components S*mask_H / S*mask_P, * so harmonic + percussive ≈ S at margin=1 — NOT the raw median-filtered * spectrograms the legacy pleco copies returned. * * @param {Array>|Array>} S * Spectrogram [freq][time]; magnitude rows (typed arrays welcome) or * complex {real, imag} bins (phase is reapplied to the output). * @param {Object} [options] * @param {number|Array} [options.kernel_size=31] - Median kernel; scalar or [harmonic, percussive] * @param {number} [options.power=2.0] - Soft-mask exponent (Infinity → hard mask) * @param {boolean} [options.mask=false] - Return the masks themselves instead of components * @param {number|Array} [options.margin=1.0] - Mask margin(s) >= 1; scalar or [harmonic, percussive] * @returns {{harmonic: Array, percussive: Array}} Components (or masks), same layout as S * @throws {Error} On empty input or margin < 1 */ export function hpss(S: Array> | Array>, { kernel_size, power, mask, margin }?: { kernel_size?: number | Array; power?: number; mask?: boolean; margin?: number | Array; }): { harmonic: any[]; percussive: any[]; }; export { processAudioToFingerprints, optimizeEqCurves, reconstructVocal } from "../scripts/xa-vocal-separation.js";