wave-roll
Version:
JavaScript Library for Comparative MIDI Piano-Roll Visualization
141 lines • 5.07 kB
TypeScript
/**
* Segment Validator for Piano Roll Evaluation
*
* This utility validates that note segmentation (splitting) is performed correctly
* according to mir_eval standards. It checks:
*
* 1. Duration conservation: Sum of segment durations equals original note duration
* 2. Temporal continuity: No gaps or overlaps between segments
* 3. Boundary accuracy: Segment boundaries align with intersection calculations
* 4. Type consistency: Segment types match expected evaluation categories
* 5. Visual consistency: Color assignments are correct for each segment type
*/
import type { ColoredNote } from '@/core/playback';
export interface SegmentValidationOptions {
/** Tolerance for floating-point comparisons (default: 1e-6) */
tolerance: number;
/** Whether to validate segment types */
validateTypes: boolean;
/** Whether to validate color assignments */
validateColors: boolean;
/** Expected segment types in order (if known) */
expectedTypes?: ('intersection' | 'exclusive' | 'ambiguous')[];
/** Minimum segment duration to consider valid */
minSegmentDuration?: number;
}
export interface SegmentValidationResult {
/** Whether all validations passed */
isValid: boolean;
/** Severity level: 'error' | 'warning' | 'info' */
severity: 'error' | 'warning' | 'info';
/** List of validation errors */
errors: ValidationError[];
/** List of validation warnings */
warnings: ValidationWarning[];
/** Calculated metrics */
metrics: SegmentMetrics;
/** Detailed segment analysis */
segmentAnalysis: SegmentAnalysis[];
}
export interface ValidationError {
type: 'duration_mismatch' | 'temporal_gap' | 'temporal_overlap' | 'invalid_type' | 'invalid_color' | 'zero_duration';
message: string;
segmentIndex?: number;
expectedValue?: number;
actualValue?: number;
tolerance?: number;
}
export interface ValidationWarning {
type: 'small_segment' | 'color_inconsistency' | 'type_mismatch';
message: string;
segmentIndex?: number;
recommendation?: string;
}
export interface SegmentMetrics {
/** Total duration of all segments */
totalSegmentDuration: number;
/** Original note duration */
originalDuration: number;
/** Duration conservation ratio (should be 1.0) */
durationConservationRatio: number;
/** Number of segments */
segmentCount: number;
/** Average segment duration */
averageSegmentDuration: number;
/** Minimum segment duration */
minSegmentDuration: number;
/** Maximum segment duration */
maxSegmentDuration: number;
/** Total temporal gaps between segments */
totalGaps: number;
/** Total temporal overlaps between segments */
totalOverlaps: number;
/** Segment type distribution */
typeDistribution: Record<string, number>;
/** Color consistency score (0-1) */
colorConsistencyScore: number;
}
export interface SegmentAnalysis {
/** Index of the segment */
index: number;
/** Start time of segment */
startTime: number;
/** End time of segment */
endTime: number;
/** Duration of segment */
duration: number;
/** Segment type */
type?: 'intersection' | 'exclusive' | 'ambiguous';
/** Color of segment */
color: number;
/** Whether this segment has evaluation flags */
isEvalSegment: boolean;
/** Gap to next segment (if any) */
gapToNext?: number;
/** Overlap with next segment (if any) */
overlapWithNext?: number;
/** Validation issues specific to this segment */
issues: string[];
}
export declare class SegmentValidator {
private readonly defaultOptions;
/**
* Validates note segmentation for a single original note
*/
validateNoteSegmentation(originalNote: any, segments: ColoredNote[], options?: Partial<SegmentValidationOptions>): SegmentValidationResult;
/**
* Validates multiple notes at once and provides aggregate statistics
*/
validateMultipleNotes(noteValidations: Array<{
originalNote: any;
segments: ColoredNote[];
noteId?: string;
}>, options?: Partial<SegmentValidationOptions>): {
overallValid: boolean;
individualResults: Array<SegmentValidationResult & {
noteId?: string;
}>;
aggregateMetrics: AggregateMetrics;
};
private validateDurationConservation;
private validateTemporalContinuity;
private validateSegmentTypes;
private validateColorAssignments;
private calculateMetrics;
private analyzeSegments;
private calculateAggregateMetrics;
private groupByType;
}
export interface AggregateMetrics {
totalNotes: number;
validNotes: number;
validationRate: number;
totalErrors: number;
totalWarnings: number;
errorsByType: Record<string, number>;
warningsByType: Record<string, number>;
averageDurationConservation: number;
averageColorConsistency: number;
}
export declare const segmentValidator: SegmentValidator;
//# sourceMappingURL=segment-validator.d.ts.map