The lead line, chord context callback, key, and generation knobs.
The counter line as note events sorted by onset; [] for an empty melody.
import { generateCounterMelody, majorKey, parseChordSymbol } from '@libraz/libcantus';
const melody = [{ pitch: 72, startBeat: 0, durationBeat: 2 }];
const counter = generateCounterMelody({
melody,
chordAt: () => parseChordSymbol('C'),
key: majorKey(0),
}); // note events below the melody, in onset order
Generate a counter melody against a lead line.
Onsets are chosen per
rhythm:'follow'places one counter note on each melody onset;'complement'fills melody rests and sustains and reinforces an occasional strong beat, spaced at least a beat apart. Each onset's pitch is picked from the safe pitches in the counter register (chord tones and consonant tensions against the sounding melody note), rejecting candidates that would form a parallel perfect interval with the melody or sit on the wrong side of it, then scored to favour contrary or oblique motion, imperfect consonance, and stepwise movement. Ties break toward the lower pitch, so a given seed always yields the same line. Notes extend to the next counter onset (the last to the melody's end) at a velocity slightly under the melody.