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

    Function motifGraph

    • Read a melody's motif statements as a derivation forest.

      Every statement after the first is compared against every statement that precedes it: the pair relateMotifs can name outranks any it cannot, the closest-scoring precedent among equals outranks the rest, and a statement whose best precedent is neither named nor close enough by melodicSimilarity is a root — new material, not a derivation of what came before it. The derivation traced this way explains a subject restated, transposed, inverted, augmented, or loosely varied by what it grew out of, and leaves a truly new idea unattached rather than forcing it onto whatever came earliest.

      motifs is read against line rather than against its own prime statements: an occurrence's notes can differ from the motif's first statement in duration even where their intervals and onset gaps agree, and a retrograde reading depends on that duration. So every occurrence is read back off line and named fresh, occurrence to occurrence.

      Parameters

      • line: readonly NoteEvent[]

        The melody motifs was extracted from. Notes that never sound are dropped, exactly as extractMotifs drops them, so the two agree on which note an occurrence's noteIndex addresses.

      • motifs: readonly MotifData[]

        The motifs to graph, as extractMotifs reports them.

      • opts: MotifGraphOptions = {}

        Key context, the variation threshold, and a work budget; see MotifGraphOptions.

      Returns MotifGraph

      The statements as nodes, and the derivation drawn to each from an earlier one.

      import { extractMotifs, motifGraph } from '@libraz/libcantus';
      const notes = [
      { pitch: 60, startBeat: 0, durationBeat: 1 },
      { pitch: 62, startBeat: 1, durationBeat: 1 },
      { pitch: 64, startBeat: 2, durationBeat: 1 },
      { pitch: 67, startBeat: 4, durationBeat: 1 },
      { pitch: 69, startBeat: 5, durationBeat: 1 },
      { pitch: 71, startBeat: 6, durationBeat: 1 },
      ];
      const graph = motifGraph(notes, extractMotifs(notes));
      graph.edges[0]?.relation?.kind; // 'transposition'