Zongzi. Score. Note
(zongzi v0.3.0)
Copy Markdown
Domain models and structures related to musical notes.
Summary
Functions
Update note's duration.
Drags a note to a new key and/or start tick.
Fetches metadata.
Merges two notes.
Create new note.
Removes metadata.
Splits a note at an absolute tick position.
Modify the properties of an existing struct (modify id is not allowed).
Updates the note's annotation.
Update note's lyric.
Merges new metadata into the note's current metadata.
Validates a note.
Types
metadata is scope => inner.
It must be serializable.
list, doct, string, number, nil, etc.
@type t() :: %Zongzi.Score.Note{ annotation: String.t() | nil, duration_tick: Zongzi.Score.Tick.t(), id: Zongzi.Util.ID.t(), key: Zongzi.Score.Key.t(), lyric: String.t() | nil, metadata: metadata(), seq_id: Zongzi.Timeline.SeqID.t() | nil, start_tick: Zongzi.Score.Tick.t() }
Functions
@spec drag_duration(t(), non_neg_integer()) :: {:ok, t()} | {:error, term()}
Update note's duration.
@spec drag_note( t(), %{ optional(:start_tick) => Zongzi.Score.Tick.t(), optional(:key) => Zongzi.Score.Key.t() } | keyword(Zongzi.Score.Tick.t() | Zongzi.Score.Key.t()) ) :: {:ok, t()} | {:error, term()}
Drags a note to a new key and/or start tick.
Only modifies the note itself; overlap constraints are enforced downstream.
Options
Accepts a map or keyword list. Only the following keys are recognised:
:start_tick— new start tick:key— new pitch
Fetches metadata.
get_metadata/1returns all metadata.get_metadata/2returns{:error, {:key_not_found, key}}when the key is absent.
Merges two notes.
merged_id is injected by the caller — Note does not generate IDs.
Options
:gap_tolerance— maximum allowed gap between notes in ticks (default 0: must be adjacent or overlapping):lyric_merger— pluggable lyric concatenation function (fn/2 -> ok | error); defaults to concatenating when both are non-nil:annotation_merger— pluggable annotation merge function (fn/2 -> ok | error); defaults to the first non-nil value
Behaviour
- Both notes must share the same pitch (compared via
Key.to_midi/1) - Must overlap, or gap ≤
gap_tolerance - Returns
{:ok, merged_note}with the givenmerged_id - Merged annotation takes the first non-nil value
Create new note.
seq_id 默认由下游 Timeline.insert_note/2 分配,
反序列化时可以显式传入已有的 :seq_id。
Examples
iex> new(%{id: "Note_12345"})
{:ok, %Note{id: "Note_12345"}}
iex> new(%{})
{:error, {:missing_id, "Note_"}}
Removes metadata.
Typically used at the end of a plugin lifecycle or before serialization.
@spec split(t(), Zongzi.Score.Tick.t(), Zongzi.Util.ID.t(t()), map() | keyword()) :: {:ok, t(), t()} | {:error, term()}
Splits a note at an absolute tick position.
Returns {:ok, note_before, note_after}. The trailing note gets a new ID.
split_tick must fall strictly inside the note (start_tick < split_tick < end_tick).
attrs optionally overrides fields on the trailing note (e.g. a different lyric).
Modify the properties of an existing struct (modify id is not allowed).
Updates the note's annotation.
Annotations are UI-only; the engine and plugins do not read them.
Update note's lyric.
Merges new metadata into the note's current metadata.
Validates a note.
The following are invalid:
start_tickorduration_tickis negativelyricis neithernilnor a string