Subsystem

subsequence.melodic_state

The API reference for MelodicState.

MelodicState

class MelodicState(
    key: typing.Optional[str] = None,
    mode: typing.Optional[str] = None,
    low: int = 48,
    high: int = 72,
    nir_strength: float = 0.5,
    chord_weight: float = 0.4,
    rest_probability: float = 0.0,
    pitch_diversity: float = 0.6,
    tessitura_strength: float = 0.0,
)

Persistent melodic context that applies NIR scoring to single-note lines.

Initialise a melodic state for a given key, mode, and MIDI register.

Parameters

Members: choose_next, chord_weight, clone, configure_defaults, factors, high, history, key, low, mode, nir_strength, pitch_diversity, record, rest_probability, set_pool, tessitura_strength

MelodicState.key

MelodicState.key

MelodicState.mode

MelodicState.mode

MelodicState.low

MelodicState.low

MelodicState.high

MelodicState.high

MelodicState.nir_strength

MelodicState.nir_strength

MelodicState.chord_weight

MelodicState.chord_weight

MelodicState.rest_probability

MelodicState.rest_probability

MelodicState.pitch_diversity

MelodicState.pitch_diversity

MelodicState.tessitura_strength

MelodicState.tessitura_strength

MelodicState.factors

MelodicState.factors: typing.List[ScoringFactor]

MelodicState.history

MelodicState.history: typing.List[int]

MelodicState.configure_defaults

MelodicState.configure_defaults(
    key: typing.Optional[str],
    mode: typing.Optional[str],
) -> None

Adopt the surrounding key/scale where this state left them unset.

Called by p.melody() every build. It tracks the builder's current key/scale (which is the section's effective key under a form), so a state placed across sections follows each section's key — its melodic history is untouched, only the pitch pool and tonic move. An explicit constructor key/scale or an explicit pool always wins and is never overridden.

MelodicState.set_pool

MelodicState.set_pool(pitches: typing.Sequence[int]) -> None

Replace the pitch pool with explicit MIDI pitches — the experimental seam.

Admits sieve output, non-octave organisations, or any hand-picked pool; key/mode no longer constrain candidates (the tonic pitch class, for Rule C, stays the key's).

MelodicState.clone

MelodicState.clone() -> MelodicState

An independent copy — settings, factors, pool, and history.

Value constructors (Motif.generate) copy the state they are given and walk the copy, so a module-level live state is never mutated by building a value.

MelodicState.choose_next

MelodicState.choose_next(
    chord_tones: typing.Optional[typing.List[int]],
    rng: random.Random,
    beat: typing.Optional[float] = None,
    position: typing.Optional[float] = None,
    contour_target: typing.Optional[float] = None,
) -> typing.Optional[int]

Score all pitch-pool candidates and return the chosen pitch, or None for a rest.

beat (the note's beat within its cycle), position (0–1 through a generated span), and contour_target (the envelope's height there) thread caller context into the scoring factors.

MelodicState.record

MelodicState.record(pitch: int) -> None

Append a pitch to the melodic history (capped at 4 entries).

Public so pinned notes — chosen by fiat, not by the walk — still enter the NIR context.