@libraz/libcantus - v1.1.0
    Preparing search index...

    Function createArrangementSession

    • Open an arrangement analysis that can be updated a few beats at a time.

      The first pass is an ordinary analyzeArrangement; what the session adds is the slot-level evidence behind it, so a later ArrangementSession.update can work out which beats an edit could possibly have changed and leave the rest of the harmony alone. An update returns a new session, so the analysis before an edit stays valid and a host can keep it for undo.

      What an update recomputes is derived rather than guessed at:

      • The edited beats are the beats covered by the notes the old and new track arrays disagree on, which is narrower than the track and usually far narrower than the piece.
      • A slot's evidence sees exactly the notes overlapping it, so the slots to re-derive are the slots overlapping those beats — plus one either side, so that an onset sitting a floating-point hair off a slot boundary cannot leave a stale slot behind.
      • The boundary search itself has no such margin. It is a shortest-path search over a whole run of slots, so a changed slot can move a boundary anywhere in the run, and its change cost is calibrated on the mean weight of every sounding slot in the piece, which couples the runs to one another. The search is therefore re-run over the whole piece — arithmetic over the carried-over evidence, with nothing allocated per slot — rather than being spliced at a margin that does not exist.
      • Each settled segment's chord is carried over when its bounds, its key and its slots are all unchanged, since those are the only things chord inference reads.

      Key regions and the per-note annotations are recomputed in full. Both are whole-piece passes — the key search is a shortest-path search with no reset points, sub-voice lane assignment is greedy from the first note, and every note is judged against the other voices sounding beneath it — so neither has a sound local answer, and reporting one would mean an update that quietly disagreed with a fresh analysis.

      An update falls back to a full analysis whenever the edit moves the ground the evidence stands on: a changed piece length, a changed first onset (both of which move the slot grid), or an edit to a session whose harmony was supplied through ArrangementOptions.timeline. The answer is the same either way; only the work differs.

      Parameters

      Returns ArrangementSession

      A session holding the analysis and the evidence behind it.

      import { createArrangementSession } from '@libraz/libcantus';
      const melody = [{ pitch: 60, startBeat: 0, durationBeat: 4 }];
      const session = createArrangementSession([{ role: 'melody', notes: melody }]);
      const moved = [{ pitch: 62, startBeat: 0, durationBeat: 4 }];
      const next = session.update([{ trackIndex: 0, notes: moved }]);
      next.analysis.timeline.segments; // as if analyzed from scratch