Phase 7: Add MIDI clips, instrument and piano roll
This commit is contained in:
parent
8a37090b81
commit
cacc086805
38 changed files with 1373 additions and 74 deletions
73
docs/MIDI.md
Normal file
73
docs/MIDI.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# 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.
|
||||
All MIDI clips and live input share one mono instrument mix. 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, 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
|
||||
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. Equal-offset events retain input order. Other messages are
|
||||
ignored; sustain, 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, velocity editor, MIDI recording,
|
||||
SMF import, undo or piano-roll zoom yet.
|
||||
|
||||
## 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue