Play preview through the edited track's instrument

StuffMIDIMessage feeds the virtual MIDI keyboard, which only reaches
tracks that are armed and monitoring -- normally not the track whose
item you are editing. Opening an item in grid mode therefore sounded
every preview through whatever instrument happened to be armed, which
is confusing when the notes you are writing come back in the wrong
voice.

Grid mode now borrows the record routing: the edited take's track is
armed and monitoring with all MIDI inputs (anything narrower can
exclude the virtual keyboard), and every other armed track is stood
down so it cannot answer as well. The prior arm, monitor and input of
each track touched is saved by GUID in transient ExtState.

routePreview re-points lazily, so moving the editor to an item on
another track costs nothing until the target actually changes. The
daemon hands the routing back when grid mode goes off, when the editor
closes, or on exit -- the same way it already restores the loop and
repeat state the loop-bar action borrows -- so the project is put back
even if grid mode is never toggled off.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-24 00:55:25 +02:00
co-authored by Claude Opus 5
parent 2fe9fa75b2
commit 0acb7d58f6
7 changed files with 180 additions and 8 deletions
+10 -3
View File
@@ -53,9 +53,16 @@ loop/repeat state — add it to the daemon loop, not to an action.
**ExtState section `midigrid`** is the only state. Persisted (`M.set`/`M.get`):
`active`, `hold`, `root`, `scale`, `vel`, `velstep`, `chan`, `previewdur`,
`stoplead`. Transient (`M.setTemp`/`M.getTemp`, persist flag false): `seq`,
`pitches`, `dur`, `hb`, `stopat`, `stoparm`, `savedloop`, `savedrep`. Preview
traffic must stay transient — persisting it would write `reaper.ini` on every
keypress.
`pitches`, `dur`, `hb`, `stopat`, `stoparm`, `savedloop`, `savedrep`,
`savedarm`, `routed`. Preview traffic must stay transient — persisting it
would write `reaper.ini` on every keypress.
**Preview is routed to the edited track.** `StuffMIDIMessage` feeds the virtual
MIDI keyboard, which only reaches armed, monitoring tracks, so `M.routePreview`
borrows the record arm/monitor/input of the take's track (standing down other
armed tracks) and `M.restoreRouting` hands it all back. `M.preview` re-points
lazily on every call, so switching items just works. The daemon restores when
grid mode goes off, the editor closes, or REAPER exits.
**Every grid key falls back.** When grid mode is off, each bound key forwards to
what it did before via `G.passThrough` (e.g. `_OSARA_PREVCHORD`, or a numeric