60ms was too blunt: at 180 BPM a 32nd note is 42ms, so the lead swallowed the final 32nd of the bar, and it swallowed a whole 32nd from 125 BPM upward. Testing against GetPlayPosition2 rather than GetPlayPosition removes the render-ahead from the equation -- it reports the block about to be rendered rather than what is currently audible -- so the lead only has to cover the daemon's polling interval, not both delays. 35ms suffices, which is safe for 32nds to about 214 BPM. Polling cannot do better than its own interval, so for genuine precision Ctrl+Alt+Shift+Space loops the bar via the loop points instead, letting the audio engine own the boundary. That is sample accurate at any tempo or grid size. It borrows loop range and repeat state; the daemon restores both once transport stops, including when stopped with Space.
13 lines
426 B
Lua
13 lines
426 B
Lua
--[[
|
|
MIDI Grid: loop the bar the cursor is in.
|
|
|
|
Sample-accurate at the bar line, because REAPER's audio engine owns the
|
|
boundary rather than a polling loop -- so the next bar's downbeat never
|
|
leaks in, at any tempo. Repeats until you press Space.
|
|
]]
|
|
local dir = ({ reaper.get_action_context() })[2]:match("@?(.*[\\/])")
|
|
local G = dofile(dir .. "midigrid_lib.lua")
|
|
|
|
local bar = G.loopBar()
|
|
G.say("Looping bar " .. bar)
|