Files
midigrid/MidiGrid_OpenInGrid.lua
T
TalonandClaude Opus 5 0acb7d58f6 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>
2026-08-24 00:55:25 +02:00

44 lines
1.5 KiB
Lua

--[[
MIDI Grid: open the selected item in the MIDI editor and enter grid mode.
This is the counterpart to the normal "open in MIDI editor" action: it does
the same thing, then arms grid mode and announces the starting state, so a
single keystroke takes you from a selected item to writing notes.
]]
local dir = ({ reaper.get_action_context() })[2]:match("@?(.*[\\/])")
local G = dofile(dir .. "midigrid_lib.lua")
local item = reaper.GetSelectedMediaItem(0, 0)
if not item then G.say("No item selected") return end
local take = reaper.GetActiveTake(item)
if not take or not reaper.TakeIsMIDI(take) then G.say("Selected item is not MIDI") return end
-- Item: Open in built-in MIDI editor (set default behaviour in preferences)
reaper.Main_OnCommand(40153, 0)
local hwnd = reaper.MIDIEditor_GetActive()
if not hwnd then G.say("Could not open MIDI editor") return end
G.set("active", 1)
-- Preview must sound through this track's instrument, whatever else is armed.
G.routePreview(reaper.MIDIEditor_GetTake(hwnd) or take)
-- Start at the item's beginning so the first cell is the item's first cell.
local pos = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
reaper.SetEditCurPos(pos, true, false)
local p = G.getPitch(hwnd)
if not G.inScale(p) then
local up = G.scaleStep(p, 1)
if up then p = up ; G.setPitch(hwnd, p) end
end
G.say(("Grid mode on, %s, grid %s, %s, %s, %s"):format(
G.scaleName(),
G.gridLabel(G.gridQN(take)),
G.isHold() and "hold on" or "hold off",
G.noteName(p),
G.cellPosText(take)))