Second round of Lua script API updates

This commit is contained in:
Robin Gareus 2022-09-27 18:58:53 +02:00
parent 1abf6a77d6
commit 76c0f42ecb
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
23 changed files with 76 additions and 112 deletions

View File

@ -2,15 +2,15 @@ ardour { ["type"] = "Snippet", name = "Dump MIDI Region" }
function factory () return function ()
local sel = Editor:get_selection ()
local tm = Temporal.TempoMap.read ()
for r in sel.regions:regionlist ():iter () do
local mr = r:to_midiregion ()
if mr:isnil () then goto next end
print (r:name (), "Pos:", r:position (), "Start:", r:start ())
local bfc = ARDOUR.BeatsSamplesConverter (Session:tempo_map (), r:position ())
local nl = ARDOUR.LuaAPI.note_list (mr:model ())
for n in nl:iter () do
print (" Note @", bfc:to (n:time ()),
print (" Note @", n:time (), tm:sample_at_beats (n:time ()),
ARDOUR.ParameterDescriptor.midi_note_name (n:note ()),
"Vel:", n:velocity ())
end

View File

@ -19,14 +19,14 @@ function factory () return function ()
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection
for r in sel.regions:regionlist ():iter () do
-- test if it's an audio region
if r:to_audioregion ():isnil () then
local ar = r:to_audioregion()
if ar:isnil () then
goto next
end
-- to read the Region data, we use the Readable interface of the Region
-- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Readable
local a = r.to_audioregion()
local rd = a:to_readable ()
local rd = ar:to_readable ()
local n_samples = rd:readable_length ()
local n_channels = rd:n_channels ()
@ -59,7 +59,7 @@ function factory () return function ()
end
if (nonzeropos >= 0) then
msg = msg .. string.format("%s: %d\n", r:name (), nonzeropos + r:position())
msg = msg .. string.format("%s: %d\n", r:name (), nonzeropos + r:position():samples ())
else
msg = msg .. "Region: '%s' is silent\n"
end

View File

@ -31,10 +31,10 @@ function factory (params)
file = io.open ("/tmp/test" ,"a")
io.output (file)
for region in rl:iter() do
io.write (string.format ("Region: '%s' pos-changed: %s, length-changed: %s\n",
io.write (string.format ("Region: '%s' length@pos-changed: %s Start-changed: %s\n",
region:name (),
tostring (pch:containsSamplePos (ARDOUR.Properties.Position)),
tostring (pch:containsSamplePos (ARDOUR.Properties.Length))
tostring (pch:containsTimeCnt (ARDOUR.Properties.Length)),
tostring (pch:containsTimePos (ARDOUR.Properties.Start))
))
end
io.close (file)

View File

@ -21,7 +21,6 @@ function factory () return function ()
local sel = Editor:get_selection () -- get current selection
local add_undo = false -- keep track of changes
Session:begin_reversible_command ("Insert Gaps")
-- iterate over all selected tracks
@ -40,23 +39,19 @@ function factory () return function ()
region:to_stateful ():clear_changes ()
-- move region
region:set_position (region:position() + offset, 0)
region:set_position (region:position() + Temporal.timecnt_t (offset))
offset = offset + Session:nominal_sample_rate () * gap
-- create a diff of the performed work, add it to the session's undo stack
-- and check if it is not empty
if not Session:add_stateful_diff_command (region:to_statefuldestructible ()):empty () then
add_undo = true
end
Session:add_stateful_diff_command (region:to_statefuldestructible ())
end
::continue::
end
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -45,9 +45,9 @@ function factory (params)
for region in rl:iter() do
tx:send ("/region_property_changed", "sTTiii",
region:name (),
(pch:containsSamplePos (ARDOUR.Properties.Start)),
(pch:containsSamplePos (ARDOUR.Properties.Length)),
region:position (), region:start (), region:length ())
(pch:containsTimePos (ARDOUR.Properties.Start)),
(pch:containsTimeCnt (ARDOUR.Properties.Length)),
region:position ():samples(), region:start ():samples(), region:length ():samples())
end
end
end

View File

@ -3,13 +3,11 @@ ardour { ["type"] = "Snippet", name = "Region Transient List" }
function factory () return function ()
local sel = Editor:get_selection ()
for r in sel.regions:regionlist ():iter () do
local region_pos = r:position()
local region_off = r:start()
print (r:name(), r:position(), r:start())
local trans = r:transients()
local ref = r:position() - r:start()
print (r:name(), r:position(), r:start(), r:position():samples(), r:start():samples())
local trans = r:transients() -- list of samplepos_t
for t in trans:iter() do
-- print absolute timeline position of transients
print (t + region_pos - region_off)
print (ref + Temporal.timecnt_t(t), ref:samples () + t)
end
print ("----")
end

View File

@ -15,7 +15,7 @@ function factory (params) return function ()
local playlist = route:to_track():playlist ()
playlist:to_stateful ():clear_changes ()
for region in playlist:regions_at (pos):iter () do
playlist:split_region (region, ARDOUR.MusicSample (pos, 0))
playlist:split_region (region, Temporal.timepos_t (pos))
end
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
add_undo = true

View File

@ -11,6 +11,12 @@ function factory (params) return function ()
-- (regions, tracks, ranges, markers, automation, midi-notes etc)
local sel = Editor:get_selection ()
-- default track output channel count (= master bus input count)
local n_chan_out = 2
if not Session:master_out():isnil() then
n_chan_out = Session:master_out():n_inputs ():n_audio ()
end
-- for each track..
for t in sel.tracks:routelist ():iter () do
local track = t:to_track ()
@ -30,7 +36,7 @@ function factory (params) return function ()
if channels ~= 2 then goto next end
-- create 2 new tracks (using the name of the original track)(
local newtracks = Session:new_audio_track (2, 2, nil, 2, t:name(), ARDOUR.PresentationInfo.max_order, ARDOUR.TrackMode.Normal, true)
local newtracks = Session:new_audio_track (1, n_chan_out, nil, 2, t:name(), ARDOUR.PresentationInfo.max_order, ARDOUR.TrackMode.Normal, true)
assert (newtracks:size() == 2)
for r in playlist:region_list ():iter () do

View File

@ -24,7 +24,6 @@ function factory (params) return function ()
-- prepare undo operation
Session:begin_reversible_command ("Bounce+Replace Regions")
local add_undo = false -- keep track if something has changed
-- Iterate over Regions part of the selection
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection
@ -48,17 +47,12 @@ function factory (params) return function ()
-- create a diff of the performed work, add it to the session's undo stack
-- and check if it is not empty
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
add_undo = true
end
Session:add_stateful_diff_command (playlist:to_statefuldestructible ())
end
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -12,7 +12,6 @@ function factory (params) return function ()
-- prepare undo operation
-- see http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Session
Session:begin_reversible_command ("Collapse Playlists")
local add_undo = false -- keep track if something has changed
-- Track/Bus Selection -- iterate over all Editor-GUI selected tracks
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:TrackSelection
@ -46,19 +45,13 @@ function factory (params) return function ()
end
-- collect undo data
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible()):empty() then
-- is something has changed, we need to save it at the end.
add_undo = true
end
Session:add_stateful_diff_command (playlist:to_statefuldestructible())
::continue::
end
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -27,7 +27,7 @@ function factory () return function ()
for l in Session:locations():list():iter() do
if l:is_mark() and string.find (l:name(), "^" .. rv['marker'] .. ".*$") then
Session:request_locate (l:start (), false, ARDOUR.LocateTransportDisposition.RollIfAppropriate, ARDOUR.TransportRequestSource.TRS_UI)
Session:request_locate (l:start ():samples (), false, ARDOUR.LocateTransportDisposition.RollIfAppropriate, ARDOUR.TransportRequestSource.TRS_UI)
if keep then goto restart end
return
end

View File

@ -134,20 +134,20 @@ function factory (unused_params)
Session:begin_reversible_command("Add LFO automation to region")
local before = al:get_state() -- save previous state (for undo)
-- Clear events in target automation-list for the selected region.
al:clear(region:position() - region:start(), region:position() - region:start() + region:length())
al:clear(region:position() - region:start(), region:position() + region:length() - region:start())
local values = lut[wave]
local last = nil
for i = 0, cycles - 1 do
-- cycle length = region:length() / cycles
local cycle_start = region:position() - region:start() + i * region:length() / cycles
local offset = region:length() / cycles / (#values - 1)
local cycle_start = region:position() - region:start() + region:length():scale(Temporal.ratio(i, cycles))
local offset = region:length():scale (Temporal.ratio (1, cycles * (#values - 1)))
for k, v in pairs(values) do
local pos = cycle_start + (k - 1) * offset
local pos = cycle_start + offset:scale (Temporal.ratio (k - 1, 1))
if k == 1 and v ~= last then
-- Move event one sample further. A larger offset might be needed to avoid unwanted effects.
pos = pos + 1
pos = pos:increment ()
end
if k > 1 or v ~= last then
@ -167,7 +167,9 @@ function factory (unused_params)
-- Save undo
Session:add_command(al:memento_command(before, al:get_state()))
Session:commit_reversible_command(nil)
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
end
region, al, lut = nil, nil, nil
end

View File

@ -91,16 +91,12 @@ function factory () return function ()
if ec:isnil () then goto next end
if ec:list ():events ():size () == 0 then goto next end
-- MIDI events are timestamped in "bar-beat" units, we need to convert those
-- using the tempo-map, relative to the region-start
local bfc = ARDOUR.BeatsSamplesConverter (Session:tempo_map (), r:start ())
-- iterate over CC-events
for av in ec:list ():events ():iter () do
-- re-scale event to target range
local val = pd.lower + (pd.upper - pd.lower) * av.value / 127
-- and add it to the target-parameter automation-list
al:add (r:position () - r:start () + bfc:to (av.when), val, false, true)
al:add (r:position () - r:start () + av.when, val, false, true)
add_undo = true
end
::next::

View File

@ -46,7 +46,6 @@ function factory () return function ()
-- prepare undo operation
Session:begin_reversible_command ("Rubberband Regions")
local add_undo = false -- keep track if something has changed
-- for each selected region
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection
@ -141,9 +140,7 @@ function factory () return function ()
playlist:add_region (nar, r:position (), 1, false)
-- create a diff of the performed work, add it to the session's undo stack
-- and check if it is not empty
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
add_undo = true
end
Session:add_stateful_diff_command (playlist:to_statefuldestructible ())
end
::next::
@ -152,11 +149,8 @@ function factory () return function ()
::out::
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -1,8 +1,8 @@
ardour { ["type"] = "Snippet", name = "Fader Automation" }
function factory () return function ()
local playhead = Session:transport_sample ()
local samplerate = Session:nominal_sample_rate ()
local playhead = Temporal.timepos_t (Session:transport_sample ())
local samplerate = Temporal.timecnt_t (Session:nominal_sample_rate ())
-- get selected tracks
rl = Editor:get_selection ().tracks:routelist ()
@ -32,7 +32,7 @@ function factory () return function ()
for i=0,50 do
-- use a sqrt fade-out (the shape is recognizable, and otherwise
-- not be possible to achieve with existing ardour fade shapes)
al:add (playhead + i * samplerate / 50,
al:add (playhead + samplerate:scale (Temporal.ratio (i, 50)),
g * (1 - math.sqrt (i / 50)),
false, true)
end

View File

@ -2,8 +2,8 @@ ardour { ["type"] = "Snippet", name = "Plugin automation" }
function factory () return function ()
-- query playhead position and session sample-rate
local playhead = Session:transport_sample ()
local samplerate = Session:nominal_sample_rate ()
local playhead = Temporal.timepos_t (Session:transport_sample ())
local samplerate = Temporal.timecnt_t (Session:nominal_sample_rate ())
-- get Track/Bus with RID 3
local r = Session:get_remote_nth_route(3)
@ -30,7 +30,7 @@ function factory () return function ()
-- add new data points after the playhead 1 sec, min..max
-- without guard-points, but with initial (..., false, true)
for i=0,10 do
cl:add (playhead + i * samplerate / 10,
cl:add (playhead + samplerate:scale (Temporal.ratio (i, 10)),
pd.lower + math.sqrt (i / 10) * (pd.upper - pd.lower),
false, true)
end

View File

@ -11,20 +11,19 @@ function factory () return function ()
-- prepare undo operation
Session:begin_reversible_command ("Lua Region Gain")
local add_undo = false -- keep track if something has changed
-- iterate over selected regions
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection
for r in sel.regions:regionlist ():iter () do
-- test if it's an audio region
if r:to_audioregion ():isnil () then
local ar = r:to_audioregion ()
if ar:isnil () then
goto next
end
-- to read the Region data, we use the Readable interface of the Region
-- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:AudioReadable
local a = r.to_audioregion
local rd = a:to_readable ()
local rd = ar:to_readable ()
local n_samples = rd:readable_length ()
local n_channels = rd:n_channels ()
@ -64,20 +63,14 @@ function factory () return function ()
-- apply gain
r:to_audioregion (): set_scale_amplitude (1 / peak)
-- save changes (if any) to undo command
if not Session:add_stateful_diff_command (r:to_statefuldestructible ()):empty () then
add_undo = true
end
Session:add_stateful_diff_command (r:to_statefuldestructible ())
end
::next::
end
-- all done. now commit the combined undo operation
if add_undo then
-- the 'nil' command here means to use all collected diffs
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -30,7 +30,7 @@ function factory () return function ()
-- add some new ones
for i=0,50 do
al:add (i * r:length () / 50,
al:add (r:length ():scale (Temporal:ratio (i, 50)),
1 - math.sqrt (i / 50),
false, true)
end

View File

@ -11,8 +11,13 @@ function factory () return function ()
--
-- Range selection, total span of all ranges (0, 0 if no time range is selected)
if sel.time:start () < sel.time:end_sample () then
print ("Total Range:", sel.time:start (), sel.time:end_sample ())
if sel.time:start_sample () < sel.time:end_sample () then
print ("Total Range:", sel.time:start_sample (), sel.time:end_sample ())
end
-- .. and the same in Temporal.timepos_t
if sel.time:start_time () < sel.time:end_time () then
print ("Total Range:", sel.time:start_time (), sel.time:end_time ())
end
-- Range selection, individual ranges.
@ -50,7 +55,7 @@ function factory () return function ()
----------------------------------------------------------
-- The total time extents of all selected regions and ranges
local ok, ext = Editor:get_selection_extents (0, 0)
local ok, ext = Editor:get_selection_extents (Temporal.timepos_t(0), Temporal.timepos_t(0))
if ok then
print ("Selection Extents:", ext[1], ext[2])
else

View File

@ -14,7 +14,6 @@ function factory (params) return function ()
-- prepare undo operation
-- see http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Session
Session:begin_reversible_command ("Auto Region Split")
local add_undo = false -- keep track if something has changed
-- Track/Bus Selection -- iterate over all Editor-GUI selected tracks
-- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:TrackSelection
@ -40,7 +39,7 @@ function factory (params) return function ()
if l:is_mark() then
-- get all regions on the given track's playlist (may be stacked)
for reg in playlist:regions_at (l:start ()):iter () do
playlist:split_region (reg, ARDOUR.MusicSample (l:start(), 0))
playlist:split_region (reg, l:start())
-- the above operation will invalidate the playlist's region list:
-- split creates 2 new regions.
--
@ -51,20 +50,14 @@ function factory (params) return function ()
end
-- collect undo data
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
-- is something has changed, we need to save it at the end.
add_undo = true
end
Session:add_stateful_diff_command (playlist:to_statefuldestructible ())
::continue::
end
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
end end

View File

@ -19,10 +19,10 @@ function factory ()
-- 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 m = loc:first_mark_after (pos, false)
local t = Temporal.timepos_t (pos)
local m = loc:first_mark_after (t, false)
if (m == -1) then
if (m == Temporal.timepos_t.max (t:time_domain())) then
-- no marker was found
return
end
@ -40,10 +40,10 @@ function factory ()
--
-- 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) then
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, false, ARDOUR.LocateTransportDisposition.MustStop, ARDOUR.TransportRequestSource.TRS_Engine)
Session:request_locate (m:samples (), false, ARDOUR.LocateTransportDisposition.MustStop, ARDOUR.TransportRequestSource.TRS_Engine)
end
end
end

View File

@ -174,7 +174,7 @@ function factory (params) return function ()
goto errorout
end
assert (loop:start () < loop:_end ())
if loop:_end () > playhead then
if loop:_end ():samples () > playhead then
-- print_help();
print ("Error: The Playhead (paste point) needs to be after the loop.")
LuaDialog.Message ("Tom's Loop", "Error: The Playhead (paste point) needs to be after the loop.", LuaDialog.MessageType.Error, LuaDialog.ButtonType.Close):run ()
@ -249,9 +249,7 @@ function factory (params) return function ()
-- create a diff of the performed work, add it to the session's undo stack
-- and check if it is not empty
if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
add_undo = true
end
Session:add_stateful_diff_command (playlist:to_statefuldestructible ())
::continue::
end -- for all routes
@ -262,14 +260,11 @@ function factory (params) return function ()
end
-- all done, commit the combined Undo Operation
if add_undo then
-- the 'nil' Command here mean to use the collected diffs added above
if not Session:abort_empty_reversible_command () then
Session:commit_reversible_command (nil)
else
Session:abort_reversible_command ()
end
print ("bounced " .. n_regions_created .. " regions from loop range (" .. loop:length() .. " samples) to playhead @ sample # " .. playhead)
print ("bounced " .. n_regions_created .. " regions from loop range (" .. loop:length():samples() .. " samples) to playhead @ sample # " .. playhead)
::errorout::
end -- end of anonymous action script function
end -- end of script factory