Choose one scale per chord across a progression, favoring continuity.
Each chord's chordScales candidates form a stage in a Viterbi-style
dynamic program. The transition cost between adjacent choices is the number
of pitch classes that differ between their pitch-class sets (the symmetric
difference), plus a small penalty for straying from a chord's best-fit scale
so that ties break toward the tighter fit. The minimum-total-cost path is
returned, one ScaleChoice per input chord in the original order.
Each choice pairs its scale with the chord exactly as it was handed in, so
this takes plain chord data rather than the wider forms the entry points
above accept.
Choose one scale per chord across a progression, favoring continuity.
Each chord's chordScales candidates form a stage in a Viterbi-style dynamic program. The transition cost between adjacent choices is the number of pitch classes that differ between their pitch-class sets (the symmetric difference), plus a small penalty for straying from a chord's best-fit scale so that ties break toward the tighter fit. The minimum-total-cost path is returned, one ScaleChoice per input chord in the original order.
Each choice pairs its scale with the chord exactly as it was handed in, so this takes plain chord data rather than the wider forms the entry points above accept.