@libraz/libcantus - v0.9.3
    Preparing search index...

    Function harmonizeMelody

    • Harmonize a melody with a min-cost chord progression.

      The melody is segmented by harmonicRhythm; each segment is scored against diatonic (and, per reharmonize, secondary-dominant and borrowed) candidate chords by melody fit, and a Viterbi search picks the lowest-cost path using a functional-flow transition cost. When placement.transposeSearch/octaveSearch is set, the whole melody is transposed across a range and the best (transpose, progression) pair is returned; a small tessitura cost breaks ties toward placements that keep the melody in a comfortable register.

      The seed drives a deterministic tie-break only: it perturbs candidates by a magnitude far below any real cost difference (see TIE_BREAK_JITTER), so it can decide between chords or paths of otherwise-equal cost but never overrides melody fit or functional flow. For a well-determined melody the result is identical across seeds; the same seed always yields the same result.

      Parameters

      • opts: HarmonizeOptions

        Melody, key (or 'infer'), harmonic rhythm, reharmonization strength, height-search flags, and seed.

      Returns HarmonizeResult

      The chosen transpose, key, chord path, and per-note roles.

      import { harmonizeMelody, majorKey } from '@libraz/libcantus';
      const result = harmonizeMelody({
      melody: [
      { pitch: 60, startBeat: 0, durationBeat: 1 },
      { pitch: 64, startBeat: 1, durationBeat: 1 },
      ],
      key: majorKey(0),
      harmonicRhythm: 1,
      reharmonize: 'diatonic',
      placement: { transposeSearch: false, octaveSearch: false },
      });
      result.chords; // one ChordSpan per harmonic-rhythm segment