The melody to harmonize, in ascending onset order.
OptionalkeyThe key to harmonize in, or 'infer' to estimate it from the melody's
pitch-class weighting — which is what a caller who has only a melody
wants, and so the default. A key name such as 'C major' is read as that
key; 'infer' names no key and always asks for the estimate.
OptionalharmonicLength of each chord slot in beats. Harmonization places chords on a fixed grid of this length — unlike chordTimelineFromNotes, which searches for the boundaries an existing piece already implies. Any positive value is honoured; a value fine enough to make the search explode is rejected by the generation budget rather than rounded up.
Left out, it is read from ts: half a bar where the half falls on a pulse,
and the whole bar where it does not, so a waltz changes chord on its
downbeats rather than across them. In 4/4 that is one chord per half bar.
OptionaltsTime signature the melody is barred in. It weights the metric accents the chords are chosen against and sets the default chord grid, so a waltz or a jig is harmonized on its own beats rather than on a 4/4 reading of them.
OptionalreharmonizeHow far beyond the key's own triads the chord vocabulary reaches:
'diatonic' uses only them, 'secondaryDominant' adds the dominants that
tonicize each degree, and 'borrowed' adds the parallel mode's chords too.
Sugar for ctx: { complexity: { harmonic } } at the three dial positions
these names have always stood for; a context names how far the vocabulary
reaches instead of which of three steps it stops at, and wins where both
are given.
OptionalplacementWhether to search transpositions and octave placements for the melody. Both are off by default, so the melody is harmonized where it was written.
OptionalphraseBeats at which the melody's phrases end, so a longer line closes at each of them instead of only at its end.
Naming a beat asks for a close there, and three things follow from it. The beat divides the chord grid, so the slot the phrase closes in ends where the phrase does rather than running on into the next one. The harmony moves into that slot — the chord under a named close is never the chord that was already sounding, which is what makes the close audible as one. And the note the phrase comes to rest on is read as a structural tone rather than as an ornament of the next phrase's first note, so a phrase resting on the tonic is harmonized by the tonic.
Which cadence that close forms is still the melody's to decide: a phrase coming to rest on the tonic over an approach that can carry the dominant cadences authentically, and one whose approach cannot is harmonized by what it sounds.
The melody always closes where it ends, whatever this says; these are the
closes inside it. phrasesFromTimeline finds the phrases of a line
already labelled with chords, and its endBeat values are what this
expects, so a caller harmonizes a whole piece in one call rather than
harmonizing each phrase and joining the results.
A boundary landing exactly on a chord-slot boundary closes the slot before it — the beat a phrase ends on is where the next phrase begins.
OptionalctxThe generation context. Its complexity.harmonic is how far the chord
vocabulary reaches beyond the key's own triads — 0 uses them alone, 0.5 has
every secondary dominant, 1 the parallel mode's chords as well — and its
seed drives the deterministic tie-break perturbation.
OptionalbudgetUpper bound on the work this call may do. The search is one pass per
placement over every pair of candidate chords in every slot, so a long line
harmonized with placement.transposeSearch on is what needs this raised.
Options controlling harmonizeMelody.
Only
melodyis required; every other knob has the default a first call wants.