1
0
Fork 0
forked from hanez/xtc
xtc/docs/MIDI.md

76 lines
4.4 KiB
Markdown
Raw Normal View History

# 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, 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.
Phase 8 adds track mixing, automation and project undo/redo; see MIXER.md.