update and cleanup lua example scripts
authorRobin Gareus <robin@gareus.org>
Mon, 11 Apr 2016 12:36:57 +0000 (14:36 +0200)
committerRobin Gareus <robin@gareus.org>
Mon, 11 Apr 2016 12:36:57 +0000 (14:36 +0200)
scripts/a_tomsloop.lua [deleted file]
scripts/editor_test.lua [deleted file]
scripts/s_fader_automation.lua
scripts/s_foreach_track.lua
scripts/s_plugin_automation.lua
scripts/s_selection.lua [new file with mode: 0644]
scripts/tomsloop.lua [new file with mode: 0644]

diff --git a/scripts/a_tomsloop.lua b/scripts/a_tomsloop.lua
deleted file mode 100644 (file)
index f1bca82..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-ardour { ["type"] = "EditorAction", name = "Tom's Loop",
-       license     = "MIT",
-       author      = "Robin Gareus",
-       email       = "robin@gareus.org",
-       site        = "http://gareus.org",
-       description = [[Bounce the loop-range of all non muted audio tracks, paste N times at playhead]]
-}
-
-function action_params ()
-       return { ["times"]   = { title = "Number of copies to add", default = "1"}, }
-end
-
-function factory (params) return function ()
-       -- get options
-       local p = params or {}
-       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)
-
-       local loop     = Session:locations ():auto_loop_location ()
-       local playhead = Session:transport_frame ()
-
-       -- make sure we have a loop, and the playhead (edit point) is after it
-       if not loop then
-               print ("A Loop range must be set.")
-               goto errorout
-       end
-       assert (loop:start () < loop:_end ())
-       if loop:_end () >= playhead then
-               print ("The Playhead (paste point) needs to be after the loop.")
-               goto errorout
-       end
-
-       -- prepare undo operation
-       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
-               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 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 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, 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
-               if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
-                       add_undo = true
-               end
-
-               ::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' 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
diff --git a/scripts/editor_test.lua b/scripts/editor_test.lua
deleted file mode 100644 (file)
index 323d243..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-ardour {
-       ["type"]    = "EditorAction",
-       name        = "Action Test",
-       license     = "MIT",
-       author      = "Robin Gareus",
-       email       = "robin@gareus.org",
-       site        = "http://gareus.org",
-       description = [[ An Example Ardour Editor Action Plugin.]]
-}
-
-function factory (params)
-       return function ()
-               for n in pairs(_G) do print(n) end
-               print ("----")
-       end
-end
index e1ee2876e4e263043e49cbda7d7ff27462b8672b..aaac7adfe946fb25a070a7d00f930ad5e486af79 100644 (file)
@@ -1,46 +1,53 @@
-ardour { ["type"] = "Snippet", name = "fader automation" }
+ardour { ["type"] = "Snippet", name = "Fader Automation" }
 
 function factory () return function ()
        local playhead = Session:transport_frame ()
        local samplerate = Session:nominal_frame_rate ()
 
        -- get selected tracks
-       rl = Editor:get_selection().tracks:routelist()
+       rl = Editor:get_selection ().tracks:routelist ()
+
        -- prepare undo operation
        Session:begin_reversible_command ("Fancy Fade Out")
        local add_undo = false -- keep track if something has changed
-       -- iterate over selected tracks
-       for r in rl:iter() do
-               local ac = r:amp():gain_control() -- ARDOUR:AutomationControl
-               local acl = ac:alist() -- ARDOUR:AutomationControlList (state, high-level)
-               local cl = acl:list()  -- Evoral:ControlList (actual events)
 
-               ac:set_automation_state(ARDOUR.AutoState.Touch)
+       -- iterate over selected tracks
+       for r in rl:iter () do
+               local ac = r:amp ():gain_control () -- ARDOUR:AutomationControl
+               local al = ac:alist () -- ARDOUR:AutomationList (state, high-level)
+               local cl = al:list ()  -- Evoral:ControlList (actual events)
 
-               if cl:isnil() then
+               if cl:isnil () then
                        goto out
                end
 
+               -- set automation state to "Touch"
+               ac:set_automation_state (ARDOUR.AutoState.Touch)
+
                -- query the value at the playhead position
-               local g = cl:eval(playhead)
+               local g = cl:eval (playhead)
 
                -- get state for undo
-               local before = acl:get_state()
+               local before = al:get_state ()
 
                -- delete all events after the playhead...
                cl:truncate_end (playhead)
+
                -- ...and generate some new ones.
                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)
                        cl:add (playhead + i * samplerate / 50,
-                                g * (1 - math.sqrt (i / 50)),
-                                false, true)
+                               g * (1 - math.sqrt (i / 50)),
+                               false, true)
                end
+
                -- remove dense events
-               cl:thin(20)
+               cl:thin (20)
 
                -- save undo
-               local after = acl:get_state()
-               Session:add_command (acl:memento_command(before, after))
+               local after = al:get_state ()
+               Session:add_command (al:memento_command (before, after))
                add_undo = true
 
                ::out::
index 7b5d051eba2f525a30e6894286d351bc13a5c82c..c1c6ed8da14229ed5aba2cdac6b6cebd4b83285d 100644 (file)
@@ -1,11 +1,10 @@
-ardour { ["type"] = "Snippet", name = "foreach track" }
+ardour { ["type"] = "Snippet", name = "Foreach Track" }
 
 function factory () return function ()
        for r in Session:get_tracks():iter() do
                print (r:name())
                -- see http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Track
                -- for available methods e.g.
-               --
                r:set_active (true, nil)
        end
 end end
index e69de6662a760f7b8500cfa3fb0a6dde0d35971a..daec46aa0c76fbe501bea567d8881c344e4e2890 100644 (file)
@@ -1,25 +1,33 @@
-ardour { ["type"] = "Snippet", name = "plugin automation2" }
+ardour { ["type"] = "Snippet", name = "Plugin automation" }
 
 function factory () return function ()
+       -- query playhead position and session sample-rate
        local playhead = Session:transport_frame ()
        local samplerate = Session:nominal_frame_rate ()
 
+       -- get Track/Bus with RID 3
        local r = Session:route_by_remote_id(3)
-       -- get AutomationControList, ControlList and ParameterDescriptor
-       local acl, cl, pd = ARDOUR.LuaAPI.plugin_automation (r:nth_plugin (0), 0)
+       -- make sure the track object exists
+       assert (not r:isnil ())
 
-       if not acl:isnil() then
+       -- get AutomationList, ControlList and ParameterDescriptor
+       -- of the first plugin's first parameter
+       -- see http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:LuaAPI
+       local al, cl, pd = ARDOUR.LuaAPI.plugin_automation (r:nth_plugin (0), 0)
+
+       if not al:isnil () then
                print ("Parameter Range", pd.lower, pd.upper)
-               print ("Current value", cl:eval(playhead))
+               print ("Current value", cl:eval (playhead))
 
                -- prepare undo operation
                Session:begin_reversible_command ("Automatix")
-               local before = acl:get_state()
+               -- remember current AutomationList state
+               local before = al:get_state()
 
                -- remove future automation
                cl:truncate_end (playhead)
 
-               -- add new data points after the playhead 1 sec min..max
+               -- 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,
@@ -28,8 +36,8 @@ function factory () return function ()
                end
 
                -- save undo
-               local after = acl:get_state()
-               Session:add_command (acl:memento_command(before, after))
+               local after = al:get_state()
+               Session:add_command (al:memento_command(before, after))
                Session:commit_reversible_command (nil)
        end
 end end
diff --git a/scripts/s_selection.lua b/scripts/s_selection.lua
new file mode 100644 (file)
index 0000000..1963ac1
--- /dev/null
@@ -0,0 +1,60 @@
+ardour { ["type"] = "Snippet", name = "Editor Selection" }
+
+function factory () return function ()
+       -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:Selection
+       -- the Ardour Selection can include multiple items
+       -- (regions, tracks, ranges, markers, automation, midi-notes etc)
+       local sel = Editor:get_selection ()
+
+       --
+       -- At the point of writing the following data items are available
+       --
+       
+       -- Range selection, total span of all ranges (0, 0 if no time range is selected)
+       if sel.time:start () < sel.time:end_frame () then
+               print ("Total Range:", sel.time:start (), sel.time:end_frame ())
+       end
+
+       -- Range selection, individual ranges.
+       for ar in sel.time:iter () do
+               -- each of the items is a
+               -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:AudioRange
+               print ("Range:", ar.id, ar.start, ar._end)
+       end
+
+       -- Track/Bus Selection
+       -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:TrackSelection
+       for r in sel.tracks:routelist ():iter () do
+               -- each of the items is a
+               -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Route
+               print ("Route:", r:name ())
+       end
+
+       -- Region selection
+       -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:RegionSelection
+       for r in sel.regions:regionlist ():iter () do
+               -- each of the items is a
+               -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:Region
+               print ("Region:", r:name ())
+       end
+
+       -- Markers
+       -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:MarkerSelection
+       -- Note: Marker selection is not cleared and currently (Ardour-4.7) points
+       --       to the most recently selected marker.
+       for m in sel.markers:iter () do
+               -- each of the items is a
+               -- http://manual.ardour.org/lua-scripting/class_reference/#ARDOURUI::ArdourMarker
+               print ("Marker:", m:name (), m:position(), m:_type())
+       end
+
+       ----------------------------------------------------------
+       -- The total time extents of all selected regions and ranges
+       local ok, ext = Editor:get_selection_extents (0, 0)
+       if ok then
+               print ("Selection Extents:", ext[1], ext[2])
+       else
+               print ("No region or range is selected")
+       end
+
+end end
diff --git a/scripts/tomsloop.lua b/scripts/tomsloop.lua
new file mode 100644 (file)
index 0000000..f1bca82
--- /dev/null
@@ -0,0 +1,127 @@
+ardour { ["type"] = "EditorAction", name = "Tom's Loop",
+       license     = "MIT",
+       author      = "Robin Gareus",
+       email       = "robin@gareus.org",
+       site        = "http://gareus.org",
+       description = [[Bounce the loop-range of all non muted audio tracks, paste N times at playhead]]
+}
+
+function action_params ()
+       return { ["times"]   = { title = "Number of copies to add", default = "1"}, }
+end
+
+function factory (params) return function ()
+       -- get options
+       local p = params or {}
+       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)
+
+       local loop     = Session:locations ():auto_loop_location ()
+       local playhead = Session:transport_frame ()
+
+       -- make sure we have a loop, and the playhead (edit point) is after it
+       if not loop then
+               print ("A Loop range must be set.")
+               goto errorout
+       end
+       assert (loop:start () < loop:_end ())
+       if loop:_end () >= playhead then
+               print ("The Playhead (paste point) needs to be after the loop.")
+               goto errorout
+       end
+
+       -- prepare undo operation
+       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
+               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 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 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, 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
+               if not Session:add_stateful_diff_command (playlist:to_statefuldestructible ()):empty () then
+                       add_undo = true
+               end
+
+               ::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' 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