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

    Function imitate

    • Answer a leading voice with an imitation of it.

      The chosen span of the lead is copied so that its first note falls on atBeat, keeping its internal rhythm; only the answer is returned, so the caller decides what to do with the two voices together. Pitches move by interval: literally for a real answer, by scale degree for a tonal one, and upside down first when invert is set. Inversion mirrors about the first note of the copied span, so the answer starts where the transposition puts that note either way. In a tonal answer a pitch outside the key keeps its distance from the scale tone below it, and inversion mirrors that distance too — a chromatic passing note stays a chromatic passing note, on the other side. Where a mirrored chromatic note falls into a diatonic semitone the key leaves it no room, and it lands on the scale tone there, so a subject saturated with chromatic steps can answer with a pitch repeated.

      Parameters

      • lead: readonly NoteEvent[]

        The voice being imitated, in ascending onset order.

      • opts: ImitationOptions

        Where the answer enters, at what interval, and in what key.

      Returns NoteEvent[]

      The imitation as note events sorted by onset; [] when the chosen span holds no sounding notes. Notes with a zero or negative duration never sound and are not copied, so the answer can be shorter than the span. Every other field of a copied note — its articulation, and its velocity through velocityScale — comes across with it.

      If the span is reversed, the answer is not a known kind, or a transposed pitch leaves the MIDI range.

      import { imitate, majorKey } from '@libraz/libcantus';
      const lead = [0, 1, 2].map((beat) => ({ pitch: 60 + beat, startBeat: beat, durationBeat: 1 }));
      imitate(lead, { atBeat: 2, interval: 'P5', key: majorKey(0) });
      // the same three notes a fifth up, entering at beat 2