wave-roll
Version:
JavaScript Library for Comparative MIDI Piano-Roll Visualization
100 lines • 3.96 kB
TypeScript
/**
* Enhanced note-level transcription matching utilities with 1:N support.
*
* This implementation provides logical equivalence with mir_eval.transcription_velocity
* while supporting 1:N matching (currently used as 1:1 by default).
*
* Key improvements over base implementation:
* 1. Support for 1:N matching with configurable cardinality
* 2. Velocity normalization and scaling (mir_eval style)
* 3. Better handling of missing velocities
* 4. Enhanced diagnostics for matched pairs
*
* Reference: https://github.com/mir-evaluation/mir_eval
* License note: Algorithm design follows mir_eval's documented behavior,
* but code is independently implemented in TypeScript.
*/
import { ParsedMidi } from "@/lib/core/utils/midi/types";
import { TranscriptionToleranceOptions, VelocityToleranceOptions } from "./constants";
import type { SecondaryMatch } from "./types";
/**
* Enhanced match result with support for 1:N relationships
*/
export interface EnhancedNoteMatchResult {
/** 1:1 matches (primary/best match for each reference note) */
matches: Array<{
ref: number;
est: number | number[];
refPitch: number;
estPitch: number | number[];
refTime: number;
estTime: number | number[];
onsetDiff?: number | number[];
offsetDiff?: number | number[];
pitchDiff?: number | number[];
overlapRatio?: number | number[];
refVelocity?: number;
estVelocity?: number | number[];
velocityDiff?: number | number[];
/** Velocity after normalization/scaling */
estVelocityScaled?: number | number[];
/** Match confidence score [0,1] */
confidence?: number;
}>;
/** All possible matches (including secondary matches for 1:N) */
allMatches?: SecondaryMatch[];
/** Indices of unmatched reference notes */
falseNegatives: number[];
/** Indices of unmatched estimated notes */
falsePositives: number[];
/** Global velocity scaling parameters (mir_eval style) */
velocityScaling?: {
slope: number;
intercept: number;
normalized: boolean;
};
}
/**
* Options for enhanced matching
*/
export interface EnhancedMatchingOptions {
/** Maximum number of estimated notes that can match a single reference note */
maxMatchesPerRef?: number;
/** Maximum number of reference notes that can match a single estimated note */
maxMatchesPerEst?: number;
/** Use weighted bipartite matching instead of maximum cardinality */
useWeightedMatching?: boolean;
/** Apply mir_eval style velocity normalization and scaling */
applyVelocityScaling?: boolean;
}
/**
* Enhanced note matching with 1:N support and velocity scaling
*/
export declare function matchNotesEnhanced(reference: ParsedMidi, estimated: ParsedMidi, tolerances?: Partial<TranscriptionToleranceOptions>, velocityOpts?: Partial<VelocityToleranceOptions>, enhancedOpts?: EnhancedMatchingOptions): EnhancedNoteMatchResult;
/**
* Wrapper for backward compatibility with existing matchNotesWithVelocity
*/
export declare function matchNotesWithVelocityEnhanced(reference: ParsedMidi, estimated: ParsedMidi, options?: Partial<TranscriptionToleranceOptions>, velocity?: Partial<VelocityToleranceOptions>): EnhancedNoteMatchResult;
/**
* Export helper to convert enhanced result to standard format
*/
export declare function enhancedToStandardResult(enhanced: EnhancedNoteMatchResult): {
matches: Array<{
ref: number;
est: number;
refPitch: number;
estPitch: number;
refTime: number;
estTime: number;
onsetDiff?: number;
offsetDiff?: number;
pitchDiff?: number;
overlapRatio?: number;
refVelocity?: number;
estVelocity?: number;
velocityDiff?: number;
}>;
falseNegatives: number[];
falsePositives: number[];
};
//# sourceMappingURL=matchNotes-enhanced.d.ts.map