Immutable MIDI clip content: start-then-identity-ordered notes with sparse deterministic modifiers, beside the controller and expression streams those notes sound against.
More...
|
| runtime::Result< MidiContent, ModelError > | replace_note (NoteEvent note) const |
| | Returns a new snapshot replacing the note with the same identity.
|
| std::span< const NoteEvent > | notes () const noexcept |
| | Returns notes in canonical (start, id) order.
|
| std::span< const NoteModifier > | modifiers () const noexcept |
| | Sorted by note id and containing only notes whose playback differs from the default, so a document that authors no modifiers carries none.
|
| std::uint64_t | modifier_seed () const noexcept |
| | Returns the authored seed used to derive per-note probability draws.
|
| std::span< const MidiExpressionLane > | lanes () const noexcept |
| | Controller and expression streams in (address, id) order, each lane's points in (position, id) order.
|
| const MidiExpressionLane * | lane_for (const MidiLaneAddress &address) const noexcept |
| | The lane addressing address, or nullptr when the clip authors none.
|
| const NoteModifier * | modifier_for (ItemId note_id) const noexcept |
| | The modifier for note_id, or nullptr when the note plays by default.
|
|
| static runtime::Result< MidiContent, ModelError > | create (std::vector< NoteEvent > notes) |
| | Notes alone: no modifiers, no lanes, and a zero seed.
|
| static runtime::Result< MidiContent, ModelError > | create (std::vector< NoteEvent > notes, std::vector< NoteModifier > modifiers, std::uint64_t modifier_seed) |
| | Notes plus their sparse modifier companion array.
|
| static runtime::Result< MidiContent, ModelError > | create (std::vector< NoteEvent > notes, std::vector< NoteModifier > modifiers, std::uint64_t modifier_seed, std::vector< MidiExpressionLane > lanes) |
| | Notes, modifiers, seed, and the clip's controller/expression lanes.
|
Immutable MIDI clip content: start-then-identity-ordered notes with sparse deterministic modifiers, beside the controller and expression streams those notes sound against.
Notes and lanes are separate storage because they answer different questions. A note is asked "which notes start inside this block", which wants events ordered by time across the whole clip. A controller stream is asked "what was your value at this instant", which wants each stream's own history, independently searchable, so that seeking never costs a walk over unrelated streams.
Notes, modifiers, seed, and the clip's controller/expression lanes.
Every lane and point identity must be valid and distinct from every other identity this content owns, including the note identities, and no two lanes may share an address. Lanes are returned in (address, id) order and their points in (position, id) order regardless of the order supplied.
Controller and expression streams in (address, id) order, each lane's points in (position, id) order.
Both orderings are what makes a seek cheap: the stream is found by binary search over this span, and its value at an instant by binary search within that lane's points. A clip that authors no controllers carries no lanes.