UNPKG

wave-roll

Version:

JavaScript Library for Comparative MIDI Piano-Roll Visualization

93 lines 4.93 kB
/** * Note-level transcription matching utilities. * * This implementation is designed for logical equivalence with * mir_eval.transcription note matching (onset/pitch/offset gating with unique * assignment). We do not copy code from mir_eval; instead we document the * intended behaviour and provide our own TypeScript implementation. * * Reference: https://github.com/mir-evaluation/mir_eval */ import { TranscriptionToleranceOptions, VelocityToleranceOptions } from "./constants"; import { ParsedMidi } from "@/lib/midi/types"; import type { MatchEntry } from "./types"; /** * Result of a note-level matching operation. */ export interface NoteMatchResult { /** Pairs of matched reference-estimated indices */ matches: MatchEntry[]; /** Indices of unmatched reference notes */ falseNegatives: number[]; /** Indices of unmatched estimated notes */ falsePositives: number[]; } /** * Options for BPM-aware note matching. */ export interface BpmScalingOptions { /** * When true, scales the estimated MIDI's time intervals to match * the reference MIDI's BPM. This is useful when comparing MIDI files * with different tempos but the same musical content. * * Formula: scaledEstTime = estTime * (refBpm / estBpm) * * @default false */ scaleBpmToReference?: boolean; } /** * Match notes between reference and estimated MIDI representations following * the criteria used by `mir_eval.transcription.match_notes`. * * A reference and estimated note are considered a match when: * - their onsets differ by at most `onsetTolerance` seconds. * - their pitches (in MIDI) differ by at most `pitchTolerance`. * - their offsets differ by at most `max(offsetMinTolerance, offsetRatioTolerance x referenceDuration)`. * * Each reference (estimated) note can be matched to at most one estimated * (reference) note. We compute the maximum bipartite matching subject to the * above constraints (Hopcroft-Karp), which mirrors the behavior of mir_eval's * unique assignment policy. * * @param reference - The reference (ground truth) MIDI data * @param estimated - The estimated (model output) MIDI data * @param options - Tolerance options for matching * @param bpmOptions - BPM scaling options for tempo-aware matching */ export declare function matchNotes(reference: ParsedMidi, estimated: ParsedMidi, options?: Partial<TranscriptionToleranceOptions>, bpmOptions?: BpmScalingOptions): NoteMatchResult; /** * Velocity-aware matching. * * This function mirrors `matchNotes` (onset/pitch/offset gating) and optionally * adds a velocity gate to the adjacency when `velocity.includeInMatching` is true. * It preserves the same 1:1 matching policy via Hopcroft-Karp and enriches * matches with per-pair diagnostics (diffs, overlap, velocities). * * @param reference - The reference (ground truth) MIDI data * @param estimated - The estimated (model output) MIDI data * @param options - Tolerance options for matching * @param velocity - Velocity tolerance options * @param bpmOptions - BPM scaling options for tempo-aware matching */ export declare function matchNotesWithVelocity(reference: ParsedMidi, estimated: ParsedMidi, options?: Partial<TranscriptionToleranceOptions>, velocity?: Partial<VelocityToleranceOptions>, bpmOptions?: BpmScalingOptions): NoteMatchResult; /** * mir_eval-style function signature using explicit arrays. * Provided for parity with `mir_eval.transcription.match_notes`. */ export declare function match_notes(reference_intervals: [number, number][], reference_pitches: number[], estimated_intervals: [number, number][], estimated_pitches: number[], onset_tolerance?: number, pitch_tolerance?: number): NoteMatchResult; /** * mir_eval-style match with onset+pitch+offset tolerance. */ export declare function match_notes_with_offset(reference_intervals: [number, number][], reference_pitches: number[], estimated_intervals: [number, number][], estimated_pitches: number[], onset_tolerance?: number, pitch_tolerance?: number, offset_ratio_tolerance?: number, offset_min_tolerance?: number): NoteMatchResult; /** * Chroma version of match_notes where pitch is compared mod 12. */ export declare function match_notes_chroma(reference_intervals: [number, number][], reference_pitches: number[], estimated_intervals: [number, number][], estimated_pitches: number[], onset_tolerance?: number, pitch_tolerance?: number, offset_ratio_tolerance?: number, offset_min_tolerance?: number): NoteMatchResult; /** * Chroma match with onset+pitch only (no offset gating). Useful for * chroma_precision_recall_f1. */ export declare function match_notes_chroma_onset(reference_intervals: [number, number][], reference_pitches: number[], estimated_intervals: [number, number][], estimated_pitches: number[], onset_tolerance?: number, pitch_tolerance?: number): NoteMatchResult; //# sourceMappingURL=matchNotes.d.ts.map