X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=scripts%2Ftomsloop.lua;h=f1bca82068981aa94f956b96316a7c0ce6103321;hb=d32333f4efd356cd15a2dfe296219ed388d61348;hp=2a7880111e949c781c263b4571ac598c51c805fe;hpb=fcb9092e2cfb00f2ee9a20001b73d74718dc6be9;p=ardour.git diff --git a/scripts/tomsloop.lua b/scripts/tomsloop.lua index 2a7880111e..f1bca82068 100644 --- a/scripts/tomsloop.lua +++ b/scripts/tomsloop.lua @@ -1,4 +1,4 @@ -ardour { ["type"] = "Snippet", name = "Tom's Loop", +ardour { ["type"] = "EditorAction", name = "Tom's Loop", license = "MIT", author = "Robin Gareus", email = "robin@gareus.org", @@ -6,16 +6,15 @@ ardour { ["type"] = "Snippet", name = "Tom's Loop", description = [[Bounce the loop-range of all non muted audio tracks, paste N times at playhead]] } --- unused ; cfg parameter for ["type"] = "EditorAction" function action_params () return { ["times"] = { title = "Number of copies to add", default = "1"}, } end -function factory () return function () +function factory (params) return function () -- get options local p = params or {} - local npaste = p["times"] or 1 - assert (npaste > 0) + local n_paste = tonumber (p["times"] or 1) + assert (n_paste > 0) local proc = ARDOUR.LuaAPI.nil_proc () -- bounce w/o processing local itt = ARDOUR.InterThreadInfo () -- bounce progress info (unused) @@ -24,8 +23,6 @@ function factory () return function () local playhead = Session:transport_frame () -- make sure we have a loop, and the playhead (edit point) is after it - -- TODO: only print an error and return - -- TODO: use the edit-point (not playhead) ? maybe. if not loop then print ("A Loop range must be set.") goto errorout @@ -40,35 +37,67 @@ function factory () return function () Session:begin_reversible_command ("Tom's Loop") local add_undo = false -- keep track if something has changed + -- prefer solo'ed tracks + local soloed_track_found = false for route in Session:get_tracks ():iter () do - -- skip muted tracks + if route:soloed () then + soloed_track_found = true + break + end + end + + -- count regions that are bounced + local n_regions_created = 0 + + -- loop over all tracks in the session + for route in Session:get_tracks ():iter () do + if soloed_track_found then + -- skip not soloed tracks + if not route:soloed () then + goto continue + end + end + + -- skip muted tracks (also applies to soloed + muted) if route:muted () then goto continue end + + -- at this point the track is either soloed (if at least one track is soloed) + -- or not muted (if no track is soloed) + -- test if bouncing is possible local track = route:to_track () if not track:bounceable (proc, false) then goto continue end + -- only audio tracks local playlist = track:playlist () if playlist:data_type ():to_string () ~= "audio" then goto continue end - -- check if there are any regions in the loop-range of this track - local range = Evoral.Range (loop:start (), loop:_end ()) - if playlist:regions_with_start_within (range):empty () - and playlist:regions_with_end_within (range):empty () then + -- check if there is at least one unmuted region in the loop-range + local reg_unmuted_count = 0 + for reg in playlist:regions_touched (loop:start (), loop:_end ()):iter () do + if not reg:muted() then + reg_unmuted_count = reg_unmuted_count + 1 + end + end + + if reg_unmuted_count < 1 then goto continue end - -- clear existing changes, prepare "diff" of state + -- clear existing changes, prepare "diff" of state for undo playlist:to_stateful ():clear_changes () -- do the actual work local region = track:bounce_range (loop:start (), loop:_end (), itt, proc, false) - playlist:add_region (region, playhead, npaste, false) + playlist:add_region (region, playhead, n_paste, false) + + n_regions_created = n_regions_created + 1 -- create a diff of the performed work, add it to the session's undo stack -- and check if it is not empty @@ -78,12 +107,21 @@ function factory () return function () ::continue:: end + + --advance playhead so it's just after the newly added regions + if n_regions_created > 0 then + Session:request_locate((playhead + loop:length() * n_paste),false) + end + -- all done, commit the combined Undo Operation if add_undo then - -- the 'nil' Commend here mean to use the collected diffs added above + -- the 'nil' Command here mean to use the collected diffs added above Session:commit_reversible_command (nil) else Session:abort_reversible_command () end + + print ("bounced " .. n_regions_created .. " regions from loop range (" .. loop:length() .. " frames) to playhead @ frame # " .. playhead) + ::errorout:: end end