quick checks on empty control lists, to avoid unnecessary work
[ardour.git] / scripts / s_fader_automation.lua
1 ardour { ["type"] = "Snippet", name = "Fader Automation" }
2
3 function factory () return function ()
4         local playhead = Session:transport_frame ()
5         local samplerate = Session:nominal_frame_rate ()
6
7         -- get selected tracks
8         rl = Editor:get_selection ().tracks:routelist ()
9
10         -- prepare undo operation
11         Session:begin_reversible_command ("Fancy Fade Out")
12         local add_undo = false -- keep track if something has changed
13
14         -- iterate over selected tracks
15         for r in rl:iter () do
16                 local ac = r:amp ():gain_control () -- ARDOUR:AutomationControl
17                 local al = ac:alist () -- ARDOUR:AutomationList (state, high-level)
18                 local cl = al:list ()  -- Evoral:ControlList (actual events)
19
20                 if cl:isnil () then
21                         goto out
22                 end
23
24                 -- set automation state to "Touch"
25                 ac:set_automation_state (ARDOUR.AutoState.Touch)
26
27                 -- query the value at the playhead position
28                 local g = cl:eval (playhead)
29
30                 -- get state for undo
31                 local before = al:get_state ()
32
33                 -- delete all events after the playhead...
34                 cl:truncate_end (playhead)
35
36                 -- ...and generate some new ones.
37                 for i=0,50 do
38                         -- use a sqrt fade-out (the shape is recognizable, and otherwise
39                         -- not be possible to achieve with existing ardour fade shapes)
40                         cl:add (playhead + i * samplerate / 50,
41                                 g * (1 - math.sqrt (i / 50)),
42                                 false, true)
43                 end
44
45                 -- remove dense events
46                 cl:thin (20)
47
48                 -- save undo
49                 local after = al:get_state ()
50                 Session:add_command (al:memento_command (before, after))
51                 add_undo = true
52
53                 ::out::
54         end
55
56         -- all done, commit the combined Undo Operation
57         if add_undo then
58                 -- the 'nil' Commend here mean to use the collected diffs added above
59                 Session:commit_reversible_command (nil)
60         else
61                 Session:abort_reversible_command ()
62         end
63 end end