subsequence.pattern

Immutable note and pattern data types — the rendered output layer.

Defines Note (a single scheduled MIDI event) alongside the control-event records (CcEvent, RawNoteEvent, OscEvent) and Pattern, the ordered bag of events that PatternBuilder produces and the sequencer schedules. These are plain data; the building verbs live in pattern_builder.

Module Contents

class subsequence.pattern.CcEvent[source]

A MIDI non-note event (CC, pitch bend, program change, SysEx) at a pulse position.

class subsequence.pattern.Note[source]

Represents a single MIDI note.

class subsequence.pattern.OscEvent[source]

An OSC message scheduled at a pulse position within a pattern.

class subsequence.pattern.Pattern(channel: int, length: float = 16, reschedule_lookahead: float = 1, device: int = 0, mirrors: Iterable[MirrorSpec] | None = None)[source]

Allows us to define and manipulate music pattern objects.

Initialize a new pattern with MIDI channel, length in beats, and reschedule lookahead.

Parameters:
  • channel – The MIDI channel (0-15) this pattern will output to.

  • length – The duration of the pattern before it loops/rebuilds, measured in beats (e.g., 16 = 4 bars in 4/4 time). Defaults to 16.

  • reschedule_lookahead – How many beats before the end of the pattern the next cycle is built. Defaults to 1 beat. This provides a safe computational buffer so events are queued before the clock actually needs them.

  • device – Output device index (0-indexed). 0 = primary device (default).

  • mirrors – Additional (device, channel) destinations to duplicate every note, CC, pitch bend, program change, SysEx, NRPN/RPN burst, and drone event onto. Both device and channel are 0-indexed in canonical form; the user-facing entry points (decorator and runtime API on Composition) translate the user’s channel-numbering convention before storing here. An entry may carry an optional third element — a drum_note_map — so a mirrored drum hit is re-resolved by name to that device’s own note number (see Sequencer.schedule_pattern).

add_arpeggio_beats(pitches: List[int], spacing_beats: float, velocity: int = subsequence.constants.velocity.DEFAULT_VELOCITY, duration_beats: float | None = None, pulses_per_beat: int = subsequence.constants.MIDI_QUARTER_NOTE) None[source]

Add an arpeggio that cycles through pitches at regular intervals.

add_note(position: int, pitch: int, velocity: int, duration: int, origin: str | None = None, primary_unmapped: bool = False) None[source]

Add a note to the pattern at a specific pulse position.

origin is the original drum-name string when the pitch was named (e.g. "hi_hat_closed"), or None for numeric pitches. It is carried on the Note so mirror destinations can re-resolve the name through their own drum_note_map — see Sequencer.schedule_pattern.

primary_unmapped marks a named hit whose origin is absent from this pattern’s own drum_note_map but present in a mirror’s — the primary device can’t voice it, so it stays silent and only the mapping mirror(s) sound it.

add_note_beats(beat_position: float, pitch: int, velocity: int, duration_beats: float, pulses_per_beat: int = subsequence.constants.MIDI_QUARTER_NOTE, origin: str | None = None, primary_unmapped: bool = False) None[source]

Add a note to the pattern at a beat position.

origin and primary_unmapped are forwarded to add_note so the resulting Note carries the drum name and its primary-map status.

add_raw_note_beats(message_type: str, beat_position: float, pitch: int, velocity: int = 0, pulses_per_beat: int = subsequence.constants.MIDI_QUARTER_NOTE) None[source]

Add a raw Note On or Note Off event at a beat position (ignores duration).

add_sequence(sequence: List[int], spacing_pulses: int, pitch: int, velocity: int | List[int] = subsequence.constants.velocity.DEFAULT_VELOCITY, note_duration: int = 6) None[source]

Add a sequence of notes to the pattern.

add_sequence_beats(sequence: List[int], spacing_beats: float, pitch: int, velocity: int | List[int] = subsequence.constants.velocity.DEFAULT_VELOCITY, note_duration_beats: float = 0.25, pulses_per_beat: int = subsequence.constants.MIDI_QUARTER_NOTE) None[source]

Add a sequence of notes using beat durations.

on_reschedule() None[source]

Hook called immediately before the pattern is rescheduled.

class subsequence.pattern.RawNoteEvent[source]

An explicit Note On or Note Off event at a pulse position, ignoring durations. Used for drones and infinite notes.

class subsequence.pattern.Step[source]

Represents a collection of notes at a single point in time.