133 lines
7.9 KiB
Markdown
133 lines
7.9 KiB
Markdown
# MIDI clips and instrument
|
|
|
|
Phase 7 supports drawing persisted notes and live JACK MIDI input. Record still
|
|
captures audio to WAV: MIDI capture and Standard MIDI File import are deferred.
|
|
|
|
## Workflow
|
|
|
|
Add/select a track in Sequencer, choose Add MIDI clip, then Piano roll (Ctrl+4).
|
|
Creation adds an instrument-to-output route if no instrument exists. Existing
|
|
instruments retain their routes; use Modular Graph to connect them as needed.
|
|
Scheduled MIDI clips now apply their track mix/automation before summing to
|
|
paired stereo instrument buffers; live input stays centered and unassigned. No hardware ports
|
|
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, 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 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.
|
|
|
|
## Timing and ownership
|
|
|
|
The C model owns up to 4096 notes per project, with source-relative ticks at
|
|
960 ticks/quarter and constant tempo. Control-thread preparation intersects
|
|
notes with clip trims and converts boundaries to integer sample positions.
|
|
Scheduled rendering uses absolute note age: block partitions do not change
|
|
samples, and seeking into a note chases its phase. Clip ends cut notes off.
|
|
The instrument source has its own buffer, separate from external audio input
|
|
and WAV timeline playback, and routes through the ordinary graph.
|
|
|
|
Prepared ranges are immutable; only their audio owner changes voice/panic state.
|
|
Preparation allocates; rendering uses bounded preallocated storage and performs
|
|
no allocation, freeing, I/O, locks, logging or GUI calls. Project preparation
|
|
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, 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.
|
|
|
|
## Recovery and limits
|
|
|
|
Panic/F9 clears live voices and suppresses scheduled notes already started;
|
|
future timeline notes can still start. CC120/123 does this for its channel.
|
|
Stop/start and seek clear live voices and reset suppression, allowing timeline
|
|
notes to be chased again. MIDI port disconnection, xruns and callback processing
|
|
failures request panic. Control requests use lock-free generation counters;
|
|
voice state changes on the audio thread, or while stopped.
|
|
|
|
The sine instrument scales amplitude by 0.1 times velocity/127. It supports
|
|
32 simultaneous scheduled notes and a separate 32 live voices; live overflow
|
|
steals the oldest voice, and repeated channel/pitch retriggers it. Preparation
|
|
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, MIDI recording, SMF import
|
|
or piano-roll zoom yet. Note edits participate in project snapshot undo/redo.
|
|
|
|
## Verification
|
|
|
|
`make test` checks exact onset/off samples, block partition independence, trim,
|
|
seek, panic, channel handling, voice/event limits, persistence migration and
|
|
malformed files, plus callback fault recovery. `make test-gui` draws, moves and
|
|
resizes notes with FLTK events, then saves/reopens and renders them.
|
|
`make test-jack-midi` uses only software MIDI/audio ports to verify live on/off,
|
|
panic, disconnection and saved/reopened scheduled playback. JACK port discovery
|
|
may lag activation under PipeWire; the test waits before connecting.
|
|
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.
|