The candidate melody.
The plan it was written for.
Optionalopts: EvaluateCompositionOptions
The work budget.
The violations found and the fit reading.
import { evaluateComposition, planTimeline, resolveKey } from '@libraz/libcantus';
import type { CompositionPlan } from '@libraz/libcantus';
const plan: CompositionPlan = {
planVersion: 1, seed: 0, algorithmVersion: 1,
keys: [resolveKey('C major')],
meters: [{ startBeat: 0, ts: { numerator: 4, denominator: 4 } }],
span: { startBeat: 0, endBeat: 4, bars: 1 },
sections: [{ label: 'A', startBeat: 0, endBeat: 4 }],
phrases: [
{
startBeat: 0, endBeat: 4, section: 0, cadence: null, shape: 'ascending',
peakPosition: 0.5, register: { low: 60, high: 67, mean: 64 }, onsetDensity: 4, motifs: [],
},
],
harmony: [{ startBeat: 0, endBeat: 4, key: 0, roman: 'I' }],
motifs: [],
rhythm: { onsetLevels: [0, 0, 0, 1, 0, 0], interOnsetShares: new Array(17).fill(0).fill(1, 8, 9), syncopation: 0 },
};
const melody = [
{ pitch: 60, startBeat: 0, durationBeat: 1 },
{ pitch: 64, startBeat: 1, durationBeat: 1 },
{ pitch: 67, startBeat: 2, durationBeat: 1 },
{ pitch: 60, startBeat: 3, durationBeat: 1 },
];
evaluateComposition(melody, plan).violations; // []
Check a candidate melody against the plan it was written for.
The candidate is read against the plan itself — its phrases, its harmony through planTimeline, its derivations — rather than re-analyzed into a profile, so every violation and fit reading judges the melody against what the plan actually calls for.
Violations name concrete departures at a beat.
span,phraseBoundary,cadence,registerandmotifDerivationare errors.harmonyis an error, or a warning for a note inside a derived statement, where the transformation takes precedence. A derived statement passes at any pitch level its relation admits, with its durations free and its closing and out-of-register notes excused;motifDisplacedwarns when that level is not the planned one or a note was excused.peakPositionis a warning. The fit fields, one per dimension, read each planned phrase of the candidate the way a reference profile reads its phrases and measure it as compareReferences would — never folded into one score.