Keyboard- and speech-driven step entry for the MIDI editor, built for use with OSARA. Arrows walk grid cells and scale degrees, Enter toggles notes, and every position is spoken and auditioned. Uses REAPER's own edit cursor and active_note_row rather than private cursor state, so grid mode and OSARA editing stay in sync. Grid size comes from MIDI_GetGrid(), so existing grid keybindings drive it. When grid mode is off, every bound key forwards to its previous action. Preview timing lives in a background daemon so the action scripts can exit immediately -- a script still alive on the next keypress triggers REAPER's "already running" prompt and breaks key repeat.
41 lines
1.4 KiB
Lua
41 lines
1.4 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)
|
|
|
|
-- 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)))
|