ardour { ["type"] = "session", name = "Stop at Marker", license = "MIT", author = "Ardour Team", description = [[Stop the transport on every location marker when rolling forward.]] } function factory () return function (n_samples) if (not Session:transport_rolling ()) then -- not rolling, nothing to do. return end local pos = Session:transport_sample () -- current playhead position local loc = Session:locations () -- all marker locations -- find first marker after the current playhead position, ignore loop + punch ranges -- (this only works when rolling forward, to extend this example see -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Locations ) local t = Temporal.timepos_t (pos) local m = loc:first_mark_after (t, false) if (m == Temporal.timepos_t.max (t:time_domain())) then -- no marker was found return end -- due to `first_mark_after(pos)` "m" is always > "pos": -- assert(pos < m) -- -- This callback happens from within the process callback: -- -- this cycle's end = next cycle start = pos + n_samples. -- -- Note that if "m" is exactly at cycle's end, that marker -- will be at "pos" in the next cycle. Since we ask for -- "first_mark_after pos", the marker would not be found. -- -- So even though "pos + n_samples" is barely reached, -- we need to stop at "m" in the cycle that crosses or ends at "m". if (pos + n_samples >= m:samples ()) then -- asking to locate to "m" ensures that playback continues at "m" -- and the same marker will not be taken into account. Session:request_locate (m:samples (), false, ARDOUR.LocateTransportDisposition.MustStop, ARDOUR.TransportRequestSource.TRS_Engine) end end end