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

    Function voiceIndependence

    • Measure how independent a counter line is from the lead it accompanies.

      Both lines are index-aligned samples: one slot per beat (or whatever grid the caller works on), null for a rest, and a repeated note for a sustain. That is what makes the rhythmic reading possible without a duration model, and what makes a re-attacked repeated note look like a sustain unless leadAttacks / counterAttacks say otherwise. Notes must carry octaves, since separation and motion are measured between sounding pitches.

      Nothing here is a verdict. Parallel thirds report as parallel motion with a small separation, a pedal point as oblique motion, a power-chord line as a long perfect run — all facts about the texture, not faults in it.

      Parameters

      • lead: readonly (NoteData | null)[]

        The leading line, one entry per slot.

      • counter: readonly (NoteData | null)[]

        The accompanying line, aligned slot for slot with lead.

      • Optionalopts: VoiceIndependenceOptions

        Attack flags and the treatment of the fourth.

      Returns VoiceIndependenceReport

      The motion breakdown, rhythmic complementarity, separation, crossings, and the longest perfect-consonance run.

      If the two lines differ in length, if an attack array is supplied at another length than the lines, or if a note carries no octave.

      import { parseNote, voiceIndependence } from '@libraz/libcantus';
      const lead = ['C5', 'D5', 'E5'].map((n) => parseNote(n));
      const counter = ['E4', 'F4', 'G4'].map((n) => parseNote(n));
      voiceIndependence(lead, counter).motion.parallel; // 1 — a harmony line in sixths