UNPKG

wave-roll

Version:

JavaScript Library for Comparative MIDI Piano-Roll Visualization

100 lines 3.96 kB
/** * 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