make Selection::set (TrackViewList*) more efficient and emit less PI::Change signals
[ardour.git] / scripts / _fan_out_instrument.lua
1 ardour { ["type"] = "EditorAction", name = "Fan Out Instrument",
2         license     = "MIT",
3         author      = "Ardour Team",
4         description = [[Create Busses for every Instrument Output on selected Tracks]]
5 }
6
7 function factory () return function ()
8
9         local outputs = 2
10         local mst = Session:master_out();
11         if not mst:isnil() then
12                 outputs = mst:n_inputs():n_audio()
13         end
14         mst = nil -- drop reference
15
16         local sel = Editor:get_selection ()
17         for r in sel.tracks:routelist ():iter () do
18                 local proc = r:the_instrument ():to_insert()
19                 if proc:isnil () then
20                         print ("Track", r:name(), "does not have an instrument plugin")
21                         goto next
22                 end
23                 local plugin = proc:plugin(0);
24
25                 if (r:n_outputs ():n_audio() ~= proc:output_streams():n_audio()) then
26                         print ("Instrument ", proc:name(), "outputs", proc:output_streams():n_audio(), "do not match track outputs", r:n_outputs ():n_audio())
27                         goto next
28                 end
29
30                 -- collect port-group information, count target bus width
31                 local targets = {}
32                 for i = 1, proc:output_streams():n_audio() do
33                         local pd = plugin:describe_io_port (ARDOUR.DataType("Audio"), false, i - 1)
34                         local nn = proc:name() .. " " .. pd.group_name; -- TODO use track-name prefix?
35                         targets[nn] = targets[nn] or 0
36                         targets[nn] = targets[nn] + 1
37                 end
38
39                 if #targets < 2 then
40                         print ("Instrument ", proc:name(), "has only 1 output bus. Nothing to fan out.")
41                         goto next
42                 end
43
44                 -- create busses ; TODO retain order
45                 for t,c in pairs (targets) do
46                         local rt = Session:route_by_name (t)
47                         if rt:isnil () then
48                                 Session:new_audio_route (c, outputs, nil, 1, t, ARDOUR.PresentationInfo.Flag.AudioBus, ARDOUR.PresentationInfo.max_order)
49                         end
50                 end
51
52                 r:output():disconnect_all (nil)
53                 r:panner_shell():set_bypassed (true)
54
55                 -- connect the busses
56                 for i = 1, proc:output_streams():n_audio() do
57                         local pd = plugin:describe_io_port (ARDOUR.DataType("Audio"), false, i - 1)
58                         local nn = proc:name() .. " " .. pd.group_name;
59                         local rt = Session:route_by_name (nn)
60                         assert (rt)
61
62                         local op =  r:output():audio (i - 1)
63                         local ip = rt:input():audio (pd.group_channel)
64                         op:connect (ip:name())
65                 end
66
67                 ::next::
68         end
69 end end