subsequence.forms¶
Forms — the governing values for compositional structure.
Section is the payload home: a frozen (name, bars, energy, key)
leaf. Form is a frozen tuple of Sections — constructible from
Sections or plain (name, bars) tuples (lists coerce), editable by slot
(Form.replace() / Form.insert() / Form.with_energy()),
and concatenable with +. Repetition is Python:
[verse, verse, chorus] == [verse] * 2 + [chorus] — no letters DSL.
Bind a Form with composition.form(form, at_end="stop"|"hold"|"loop");
generate one from a graph form with composition.form_freeze().
Sections compose as plain Python lists that Form coerces — Section is a
leaf, not an operator algebra.
Module Contents¶
- class subsequence.forms.Form(sections: Iterable[Any], key: str | None = None, scale: str | None = None)[source]¶
A frozen sequence of Sections — the editable, bindable form value.
List-friendly: the constructor coerces
("name", bars)tuples, soForm([("verse", 8), ("chorus", 8)])andForm([Section("verse", 8), Section("chorus", 8)])are the same value. Repetition is Python list arithmetic before construction.A form may carry its own
key/scale— the form tier of the key-source chain (Section.keyoverrides it; it overrides the composition key). A whole AABA in one key with one section borrowing another isForm([...], key="A")plus aSection(..., key="F").Coerce any iterable of Sections / (name, bars) tuples.
- insert(slot: int, section: Any) Form[source]¶
Insert a section at a 1-based slot (existing sections shift right).
slotmay belen(form) + 1to append.
- replace(slot: int, section: Section | None = None, **changes: Any) Form[source]¶
Replace the section at a 1-based slot — whole, or by field.
form.replace(3, bars=16)stretches slot 3;form.replace(3, Section("drop", 16, energy=1.0))swaps it out.
- with_energy(energies: Dict[str, float]) Form[source]¶
Set the energy payload on named sections —
{"chorus": 0.9}.Every section whose name appears in the mapping takes the new value; naming a section the form does not contain raises. Energy ramps (
(start, end)tuples) live incomposition.energy(), not in the payload — a Section carries one number.
- class subsequence.forms.Section[source]¶
One section of a form — the payload home.
- energy[source]¶
The section’s energy level (0.0–1.0; the arranging dial). Read by
p.energyandmin_energy=gating; acomposition.energy()dict overrides it (the dict is the later, performance-level dial).
- key[source]¶
Optional key override — re-anchors key-relative content (degrees, romans, generated material, and key-relative section progressions bound with
section_chords) to this section’s tonic. Absolute content (note names, MIDI pitches, frozen chords) is never moved, and chord-relative content (ChordTone,Approach) tracks the sounding chord rather than the key — see the three-intent model in the docs. The live graph engine (harmony(style=...)) stays in the composition key by design (a stateful walk does not transpose mid-stream).