write_clip_notes
Write MIDI notes into an Ableton Live clip, replacing or appending to existing content, with verification.
Instructions
Write MIDI notes into a Session clip.
Returns:
Dictionary containing write confirmation, validation reports, and optional diff.
Note:
Times are in beats and clip-local, so beat 0 is the clip's own start.
With mode='replace' (the default), the clip is updated to match the provided note
list. Live's native note writing appends by default, so mode='replace' ensures a
second write updates rather than duplicates a melody (measured: 63 + 23 = 86 notes).
Ask for 'append' by name when layering notes into an existing performance. To
empty a clip without writing new notes, use delete_clip.
Use read_clip_notes to inspect existing notes before rewriting them. Use
quantize_clip to adjust timing to a grid, and transpose_clip to shift pitch
without altering rhythm.
A list straight from ``read_clip_notes`` can be written back. Live adds
``note_id`` to every note it hands out, which is identity rather than content,
so the keys in :data:`~live_maestro.music.notes.TOLERATED_NOTE_KEYS` are
dropped instead of refused and reported as ``input_keys_ignored``. Every other
unrecognised key is an error.
``pitch``, ``start_time`` and ``duration`` are never defaulted. A reader that
substitutes ``start_time=0.0`` and ``duration=0.25`` for missing keys turns a
list built with ``pos``/``dur`` (the humanise spelling) into a pile of
sixteenths stacked on beat 0, and reports success while doing it. Wrong keys are
refused before anything is sent.
A note does not come back bit-identical to the note sent. Times and durations
return with a small deviation in both directions: a sent 0.29 reads back as
0.29000010406260407 and a sent 0.18 as 0.17999994796869798, about 4e-7 relative,
and both reproduce to every digit across runs. A ``start_time`` of 2.29 comes back
as 2.290000104062604, and a duration of 0.5 comes back exactly. The cause is not
established: it is not a tick grid (no grid of 96, 192, 480 or 960 per quarter
produces those numbers) and not a single float32 conversion (float32 of 0.29 is
0.28999999). That 0.5 survives while 0.29 does not is consistent with a
binary-representable value passing through untouched, but the mechanism is not
claimed here. At 124 BPM the error is around 50 nanoseconds, so musically it is
nothing. It matters only for comparison: never test a note time for equality. The
diff run here already uses a tolerance, which is why it reports ``0 changed`` for
values that differ in the seventh decimal.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | 'replace' updates the clip content to match exactly this note list. 'append' adds to what is there, which layers new notes onto existing ones. | replace |
| slot | Yes | Clip slot index in track.clip_slots, counted from 0. A slot index is the scene the clip sits in, so slot 2 is the third scene down. | |
| notes | Yes | The notes to write into the clip. Each item declares its own fields, and the item schema carries their units. | |
| track | Yes | Track index in song.tracks, counted from 0. | |
| verify | No | True reads the notes back and reports the difference against what was asked for, at the cost of one extra read. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||