1
0
Fork 0
forked from hanez/xtc

Phase 21: add filtered MIDI composition edits and triplet piano-roll grids

This commit is contained in:
Johannes Findeisen 2026-10-27 15:34:54 +01:00
commit 73fc5eea8d
12 changed files with 796 additions and 39 deletions

View file

@ -14,9 +14,9 @@ are connected automatically. Connect a MIDI source to the backend's `midi_in`
JACK port, and route audio output explicitly to hear it while Play is running.
The piano roll shows all 128 pitches and edits clip-source time. Click blank
space to draw a one-beat note (velocity 100, channel 0); drag its body to move
space to draw a one-beat note (velocity 100, filtered channel or channel 0); drag its body to move
it, drag the right edge to resize, or right-click/Delete to remove it. Edits
snap to 1/16 notes. Escape cancels a drag. Trimmed-out source notes remain editable
snap to the configured grid (default 1/16). Escape cancels a drag. Trimmed-out source notes remain editable
and are preserved. Arrangement/note edits stop playback and are blocked during
audio recording. Save/Open preserves MIDI flags, notes and stable IDs.
@ -37,8 +37,9 @@ builds audio and MIDI candidates before committing the stopped backend state.
JACK events have sample offsets within the current block. Supported messages
are complete note on/off (including velocity-zero note on) and CC120/123 on
channels 0..15. Equal-offset events retain input order. Other messages are
ignored; sustain, bend, program changes, running status and SysEx are unsupported.
channels 0..15, plus CC7 volume, CC10 pan and CC64 sustain (see CONTROL.md).
Equal-offset events retain input order. Bend, program changes, running status
and SysEx are unsupported.
At most 256 events are accepted per block. Malformed/overflowed input discards
that block's events and triggers panic, with a MIDI-drop status counter.
@ -58,8 +59,8 @@ rejects more than 32 overlapping scheduled notes with CAPACITY. Such metadata
can be saved by the C model, but GUI Open/Play rejects it until overlap is
reduced. Immediate note-off/stealing can click; there is no envelope or limiter,
and summed voices can exceed unity. Above-Nyquist pitches are silent.
There is no per-track/channel instrument routing, velocity editor, MIDI recording,
SMF import, undo or piano-roll zoom yet.
There is no per-track/channel instrument routing, MIDI recording, SMF import
or piano-roll zoom yet. Note edits participate in project snapshot undo/redo.
## Verification
@ -74,3 +75,59 @@ Physical MIDI devices, bridge/device loss behind an unchanged port, latency and
long-running performance remain unverified. Panic/Stop provides manual recovery.
Phase 8 adds track mixing, automation and project undo/redo; see MIXER.md.
## Phase 21 composition commands
The piano-roll **Notes** menu exposes these commands. Shortcuts apply while the
piano roll has focus; use the main window Edit menu for undo/redo.
| Command | Shortcut | Behavior |
| --- | --- | --- |
| Grid | G | 1, 120, 160, 240, 320, 480 or 960 ticks |
| Filter | F | Channel -1 (all) or 0..15, inclusive pitch range 0..127 |
| Velocity and channel | V | Set either property; -1 preserves it |
| Quantize | Q | Snap starts to nearest configured grid; ties go later |
| Transpose | T / Up / Down | Semitone count / one semitone up / down |
| Repeat | Ctrl+D | Additional copies at a positive source-tick spacing |
| Select filtered | Ctrl+A | Select every note matching the current clip filter |
| Delete | Delete | Remove the single selected note or all filtered notes |
160 ticks is a sixteenth-note triplet; 320 is an eighth-note triplet.
The grid governs drawing, drag movement and minimum resize duration. At 1-tick
snap the visual grid remains 120 ticks to stay legible at the fixed zoom.
The header shows current grid, channel/pitch filter and selection scope.
Velocity also affects unselected note brightness. Preferences are session-only.
Click selects one visible note; Ctrl+A selects the whole filtered set. A click
or filter change clears that set selection. Hidden notes cannot be mouse-edited.
A channel filter also sets the channel for newly drawn notes. No lasso or
arbitrary disjoint multi-selection is provided. Moving/resizing uses the mouse;
V edits velocity/channel without changing timing, pitch or IDs. Quantization
changes starts only, preserving durations and other properties. Repetition
keeps originals and gives every copy a fresh stable ID; spacing need not equal
note length, so both overlapping patterns and rests are possible. The existing
clip source must have room for every result; extend it in Sequencer first if
needed. Source notes outside the visible arrangement trim remain editable.
All batch edits validate before mutation. Invalid pitch/range, copy counts,
capacity overflow or a note crossing the source boundary rejects the entire
operation; notes are never silently clamped, merged or shortened. Unmatched
notes, notes in other clips and unrelated properties are preserved. Each
successful command records one undo step and stops playback before model edits;
Play prepares the new engine plan. Undo/redo reinstalls the corresponding plan.
These edits use the existing persisted note fields; format remains v7.
Scheduled notes occupy [start,end), with ends counted before starts at an equal
sample for the 32-voice limit. Overlapping same-channel/pitch scheduled notes
are independent sine voices; adjacent repetitions restart phase. Live repeated
notes instead retrigger the matching channel/pitch voice, and a note-off releases
that voice (or defers release under sustain). Equal-sample live on/off/control
messages execute in caller/JACK order, with no implicit priority reordering.
The renderer rejects malformed/unsorted/out-of-range events before touching
output or runtime; raw velocity-zero note-ons decode to note-off.
`make test-composition` covers filters, property preservation, triplet rounding,
repeats/fresh IDs, rejected batch rollback, capacity, undo snapshots, equal-offset
live order, adjacent/overlapping notes, exact block partitions and seek chase.
`make test-gui` covers mouse edits and the new commands with undo/redo and engine
reinstallation. Listening and physical MIDI-device validation remain pending.