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
key: Root note of the key (e.g."C","F#","Bb"). When omitted, the state adopts the composition's key the first timep.melody()uses it (falling back to"C").mode: Scale mode name. Accepts any mode registered withscale_pitch_classes(e.g."ionian","aeolian","dorian"). When omitted, adopts the composition's scale (falling back to"ionian").low: Lowest MIDI note (inclusive) in the pitch pool.high: Highest MIDI note (inclusive) in the pitch pool.nir_strength: 0.0–1.0. Scales how strongly the NIR rules influence candidate scores. 0.0 = uniform; 1.0 = full boost.chord_weight: 0.0–1.0. Additive multiplier bonus for candidates whose pitch class belongs to the current chord tones.rest_probability: 0.0–1.0. Probability of producing a rest (returningNone) at any given step.pitch_diversity: 0.0–1.0. Exponential penalty per recent repetition of the same pitch. Lower values discourage repetition more aggressively.tessitura_strength: 0.0–1.0. Regression pull toward the centre of the register after the line strays (off by default; the generate path enables it).
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.