Only emit InstrumentInfo::Changed() on actual change
[ardour.git] / scripts / _dsp_plugin_communication.lua
1 ardour { ["type"] = "dsp", name = "DSP Plugin Communication" }
2 function dsp_ioconfig () return { { audio_in = -1, audio_out = -1} } end
3
4 function dsp_init (rate)
5         self:shmem ():allocate (1)
6 end
7
8 function dsp_configure (ins, outs)
9 end
10
11 function dsp_params ()
12         return
13         {
14                 { ["type"] = "output", name = "self", min = 0, max = 8},
15                 { ["type"] = "output", name = "gain", min = 0, max = 2},
16         }
17 end
18
19 function dsp_run (ins, outs, n_samples)
20         local ctrl = CtrlPorts:array ()
21         local route = self:route ()
22         local shmem = self:shmem ()
23
24         -- count plugins
25         local i = 0;
26         local l = 0;
27         local s = -1; -- 'self' this plugin instance
28
29         -- iterate overall plugins on this track,
30         -- find all LuaProc instances of this plugin (unique_id),
31         repeat
32                 local proc = route:nth_plugin (i)
33                 if not proc:isnil ()
34                         and not proc:to_insert():plugin (0):to_luaproc():isnil ()
35                         and proc:to_insert():plugin (0):unique_id () == self:unique_id () then
36                         if (self:id ():to_s() == proc:to_insert():plugin (0):id ():to_s()) then
37                                 s = l; -- *this* plugin instance
38                         end
39                         if l == 0 then
40                                 -- use shared-memory are of the first plugin instance for all.
41                                 --
42                                 -- (the first plugin writes there, all later plugins only read,
43                                 -- plugins on a track are executed in order, in the same thread)
44                                 shmem = proc:to_insert():plugin (0):to_luaproc():shmem ()
45                         end
46                         l = l + 1 -- count total instances of this plugin-type
47                 end
48                 i = i + 1
49         until proc:isnil ()
50
51         assert (s >= 0)
52         ctrl[1] = s;
53
54         -- calculate digital peak of all channels
55         local peak = 0
56         for c = 1,#ins do
57                 if not ins[c]:sameinstance (outs[c]) then
58                         ARDOUR.DSP.copy_vector (outs[c], ins[c], n_samples)
59                 end
60                 peak = ARDOUR.DSP.compute_peak(outs[c], n_samples, peak)
61         end
62
63
64         -- actual inter-plugin communication
65         local a = shmem:to_float (0):array ()
66         if s == 0 then
67                 -- the first plugin saves the peak
68                 a[0] = peak
69                 ctrl[2] = -1
70         else
71                 -- all later plugins display the difference to the first.
72                 if (a[0] == 0) then
73                         ctrl[2] = 1
74                 else
75                         ctrl[2] = peak / a[0]
76                 end
77         end
78 end