ec6d86d71a76c66094fdba48db8e72065af82033
[ardour.git] / libs / ardour / plugin_insert.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <string>
25
26 #include "pbd/failed_constructor.h"
27 #include "pbd/xml++.h"
28 #include "pbd/convert.h"
29
30 #include "ardour/audio_buffer.h"
31 #include "ardour/automation_list.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/debug.h"
34 #include "ardour/event_type_map.h"
35 #include "ardour/ladspa_plugin.h"
36 #include "ardour/plugin.h"
37 #include "ardour/plugin_insert.h"
38
39 #ifdef LV2_SUPPORT
40 #include "ardour/lv2_plugin.h"
41 #endif
42
43 #ifdef WINDOWS_VST_SUPPORT
44 #include "ardour/windows_vst_plugin.h"
45 #endif
46
47 #ifdef LXVST_SUPPORT
48 #include "ardour/lxvst_plugin.h"
49 #endif
50
51 #ifdef AUDIOUNIT_SUPPORT
52 #include "ardour/audio_unit.h"
53 #endif
54
55 #include "ardour/session.h"
56 #include "ardour/types.h"
57
58 #include "i18n.h"
59
60 using namespace std;
61 using namespace ARDOUR;
62 using namespace PBD;
63
64 const string PluginInsert::port_automation_node_name = "PortAutomation";
65
66 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
67         : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
68         , _signal_analysis_collected_nframes(0)
69         , _signal_analysis_collect_nframes_max(0)
70 {
71         /* the first is the master */
72
73         if (plug) {
74                 add_plugin (plug);
75                 create_automatable_parameters ();
76         }
77 }
78
79 bool
80 PluginInsert::set_count (uint32_t num)
81 {
82         bool require_state = !_plugins.empty();
83
84         /* this is a bad idea.... we shouldn't do this while active.
85            only a route holding their redirect_lock should be calling this
86         */
87
88         if (num == 0) {
89                 return false;
90         } else if (num > _plugins.size()) {
91                 uint32_t diff = num - _plugins.size();
92
93                 for (uint32_t n = 0; n < diff; ++n) {
94                         boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
95                         add_plugin (p);
96                         if (active ()) {
97                                 p->activate ();
98                         }
99
100                         if (require_state) {
101                                 /* XXX do something */
102                         }
103                 }
104
105         } else if (num < _plugins.size()) {
106                 uint32_t diff = _plugins.size() - num;
107                 for (uint32_t n= 0; n < diff; ++n) {
108                         _plugins.pop_back();
109                 }
110         }
111
112         return true;
113 }
114
115 PluginInsert::~PluginInsert ()
116 {
117 }
118
119 void
120 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
121 {
122         if (which.type() != PluginAutomation)
123                 return;
124
125         boost::shared_ptr<AutomationControl> c
126                         = boost::dynamic_pointer_cast<AutomationControl>(control (which));
127
128         if (c && s != Off) {
129                 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
130         }
131 }
132
133 ChanCount
134 PluginInsert::output_streams() const
135 {
136         assert (!_plugins.empty());
137
138         PluginInfoPtr info = _plugins.front()->get_info();
139
140         if (info->reconfigurable_io()) {
141                 ChanCount out = _plugins.front()->output_streams ();
142                 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
143                 return out;
144         } else {
145                 ChanCount out = info->n_outputs;
146                 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
147                 out.set_audio (out.n_audio() * _plugins.size());
148                 out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
149                 return out;
150         }
151 }
152
153 ChanCount
154 PluginInsert::input_streams() const
155 {
156         assert (!_plugins.empty());
157
158         ChanCount in;
159
160         PluginInfoPtr info = _plugins.front()->get_info();
161
162         if (info->reconfigurable_io()) {
163                 assert (_plugins.size() == 1);
164                 in = _plugins.front()->input_streams();
165         } else {
166                 in = info->n_inputs;
167         }
168
169         DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
170
171         if (_match.method == Split) {
172
173                 /* we are splitting 1 processor input to multiple plugin inputs,
174                    so we have a maximum of 1 stream of each type.
175                 */
176                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
177                         if (in.get (*t) > 1) {
178                                 in.set (*t, 1);
179                         }
180                 }
181                 return in;
182
183         } else if (_match.method == Hide) {
184
185                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
186                         in.set (*t, in.get (*t) - _match.hide.get (*t));
187                 }
188                 return in;
189
190         } else {
191
192                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
193                         in.set (*t, in.get (*t) * _plugins.size ());
194                 }
195
196                 return in;
197         }
198 }
199
200 ChanCount
201 PluginInsert::natural_output_streams() const
202 {
203         return _plugins[0]->get_info()->n_outputs;
204 }
205
206 ChanCount
207 PluginInsert::natural_input_streams() const
208 {
209         return _plugins[0]->get_info()->n_inputs;
210 }
211
212 bool
213 PluginInsert::has_no_inputs() const
214 {
215         return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
216 }
217
218 bool
219 PluginInsert::has_no_audio_inputs() const
220 {
221         return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
222 }
223
224 bool
225 PluginInsert::is_midi_instrument() const
226 {
227         /* XXX more finesse is possible here. VST plugins have a
228            a specific "instrument" flag, for example.
229          */
230         PluginInfoPtr pi = _plugins[0]->get_info();
231
232         return pi->n_inputs.n_midi() != 0 &&
233                 pi->n_outputs.n_audio() > 0;
234 }
235
236 void
237 PluginInsert::create_automatable_parameters ()
238 {
239         assert (!_plugins.empty());
240
241         set<Evoral::Parameter> a = _plugins.front()->automatable ();
242
243         for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
244                 if (i->type() == PluginAutomation) {
245
246                         Evoral::Parameter param(*i);
247
248                         ParameterDescriptor desc;
249                         _plugins.front()->get_parameter_descriptor(i->id(), desc);
250
251                         can_automate (param);
252                         boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
253                         add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
254                 } else if (i->type() == PluginPropertyAutomation) {
255                         Evoral::Parameter param(*i);
256                         const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
257                         if (desc.datatype != Variant::NOTHING) {
258                                 boost::shared_ptr<AutomationList> list;
259                                 if (Variant::type_is_numeric(desc.datatype)) {
260                                         list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
261                                 }
262                                 add_control (boost::shared_ptr<AutomationControl> (new PluginPropertyControl(this, param, desc, list)));
263                         }
264                 }
265         }
266 }
267 /** Called when something outside of this host has modified a plugin
268  * parameter. Responsible for propagating the change to two places:
269  *
270  *   1) anything listening to the Control itself
271  *   2) any replicated plugins that make up this PluginInsert.
272  *
273  * The PluginInsert is connected to the ParameterChangedExternally signal for
274  * the first (primary) plugin, and here broadcasts that change to any others.
275  *
276  * XXX We should probably drop this whole replication idea (Paul, October 2015)
277  * since it isn't used by sensible plugin APIs (AU, LV2).
278  */
279 void
280 PluginInsert::parameter_changed_externally (uint32_t which, float val)
281 {
282         boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
283
284         /* First propagation: alter the underlying value of the control,
285          * without telling the plugin(s) that own/use it to set it.
286          */
287
288         if (!ac) {
289                 return;
290         }
291
292         boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
293
294         if (pc) {
295                 pc->catch_up_with_external_value (val);
296         }
297
298         /* Second propagation: tell all plugins except the first to
299            update the value of this parameter. For sane plugin APIs,
300            there are no other plugins, so this is a no-op in those
301            cases.
302         */
303
304         Plugins::iterator i = _plugins.begin();
305
306         /* don't set the first plugin, just all the slaves */
307
308         if (i != _plugins.end()) {
309                 ++i;
310                 for (; i != _plugins.end(); ++i) {
311                         (*i)->set_parameter (which, val);
312                 }
313         }
314 }
315
316 int
317 PluginInsert::set_block_size (pframes_t nframes)
318 {
319         int ret = 0;
320         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
321                 if ((*i)->set_block_size (nframes) != 0) {
322                         ret = -1;
323                 }
324         }
325         return ret;
326 }
327
328 void
329 PluginInsert::activate ()
330 {
331         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
332                 (*i)->activate ();
333         }
334
335         Processor::activate ();
336 }
337
338 void
339 PluginInsert::deactivate ()
340 {
341         Processor::deactivate ();
342
343         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
344                 (*i)->deactivate ();
345         }
346 }
347
348 void
349 PluginInsert::flush ()
350 {
351         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
352                 (*i)->flush ();
353         }
354 }
355
356 void
357 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
358 {
359         // Calculate if, and how many frames we need to collect for analysis
360         framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
361                                              _signal_analysis_collected_nframes);
362         if (nframes < collect_signal_nframes) { // we might not get all frames now
363                 collect_signal_nframes = nframes;
364         }
365
366         ChanCount const in_streams = input_streams ();
367         ChanCount const out_streams = output_streams ();
368
369         ChanMapping in_map (in_streams);
370         ChanMapping out_map (out_streams);
371         bool valid;
372         if (_match.method == Split) {
373                 /* fix the input mapping so that we have maps for each of the plugin's inputs */
374                 in_map = ChanMapping (natural_input_streams ());
375
376                 /* copy the first stream's buffer contents to the others */
377                 /* XXX: audio only */
378                 uint32_t first_idx = in_map.get (DataType::AUDIO, 0, &valid);
379                 if (valid) {
380                         for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
381                                 bufs.get_audio(in_map.get (DataType::AUDIO, i, &valid)).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
382                         }
383                 }
384         }
385
386         bufs.set_count(ChanCount::max(bufs.count(), in_streams));
387         bufs.set_count(ChanCount::max(bufs.count(), out_streams));
388
389         /* Note that we've already required that plugins
390            be able to handle in-place processing.
391         */
392
393         if (with_auto) {
394
395                 uint32_t n = 0;
396
397                 for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
398
399                         boost::shared_ptr<AutomationControl> c
400                                 = boost::dynamic_pointer_cast<AutomationControl>(li->second);
401
402                         if (c->list() && c->automation_playback()) {
403                                 bool valid;
404
405                                 const float val = c->list()->rt_safe_eval (now, valid);
406
407                                 if (valid) {
408                                         c->set_value(val);
409                                 }
410
411                         }
412                 }
413         }
414
415         if (collect_signal_nframes > 0) {
416                 // collect input
417                 //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count,  " << bufs.available().n_audio() << " available" << std::endl;
418                 //std::cerr << "               streams " << input_streams().n_audio() << std::endl;
419                 //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
420
421                 _signal_analysis_inputs.set_count(input_streams());
422
423                 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
424                         _signal_analysis_inputs.get_audio(i).read_from(
425                                 bufs.get_audio(i),
426                                 collect_signal_nframes,
427                                 _signal_analysis_collected_nframes); // offset is for target buffer
428                 }
429
430         }
431
432         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
433                 (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
434                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
435                         in_map.offset_to(*t, natural_input_streams().get(*t));
436                         out_map.offset_to(*t, natural_output_streams().get(*t));
437                 }
438         }
439
440         if (collect_signal_nframes > 0) {
441                 // collect output
442                 //std::cerr << "       output, bufs " << bufs.count().n_audio() << " count,  " << bufs.available().n_audio() << " available" << std::endl;
443                 //std::cerr << "               streams " << output_streams().n_audio() << std::endl;
444
445                 _signal_analysis_outputs.set_count(output_streams());
446
447                 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
448                         _signal_analysis_outputs.get_audio(i).read_from(
449                                 bufs.get_audio(i),
450                                 collect_signal_nframes,
451                                 _signal_analysis_collected_nframes); // offset is for target buffer
452                 }
453
454                 _signal_analysis_collected_nframes += collect_signal_nframes;
455                 assert(_signal_analysis_collected_nframes <= _signal_analysis_collect_nframes_max);
456
457                 if (_signal_analysis_collected_nframes == _signal_analysis_collect_nframes_max) {
458                         _signal_analysis_collect_nframes_max = 0;
459                         _signal_analysis_collected_nframes   = 0;
460
461                         AnalysisDataGathered(&_signal_analysis_inputs,
462                                              &_signal_analysis_outputs);
463                 }
464         }
465         /* leave remaining channel buffers alone */
466 }
467
468 void
469 PluginInsert::silence (framecnt_t nframes)
470 {
471         if (!active ()) {
472                 return;
473         }
474
475         ChanMapping in_map(input_streams());
476         ChanMapping out_map(output_streams());
477
478         if (_match.method == Split) {
479                 /* fix the input mapping so that we have maps for each of the plugin's inputs */
480                 in_map = ChanMapping (natural_input_streams ());
481         }
482
483         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
484                 (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
485         }
486 }
487
488 void
489 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
490 {
491         if (_pending_active) {
492                 /* run as normal if we are active or moving from inactive to active */
493
494                 if (_session.transport_rolling() || _session.bounce_processing()) {
495                         automation_run (bufs, start_frame, nframes);
496                 } else {
497                         connect_and_run (bufs, nframes, 0, false);
498                 }
499
500         } else {
501                 uint32_t in = input_streams ().n_audio ();
502                 uint32_t out = output_streams().n_audio ();
503
504                 if (has_no_audio_inputs() || in == 0) {
505
506                         /* silence all (audio) outputs. Should really declick
507                          * at the transitions of "active"
508                          */
509
510                         for (uint32_t n = 0; n < out; ++n) {
511                                 bufs.get_audio (n).silence (nframes);
512                         }
513
514                 } else if (out > in) {
515
516                         /* not active, but something has make up for any channel count increase */
517
518                         // TODO: option round-robin (n % in) or silence additional buffers ??
519                         // for now , simply replicate last buffer
520                         for (uint32_t n = in; n < out; ++n) {
521                                 bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
522                         }
523                 }
524
525                 bufs.count().set_audio (out);
526         }
527
528         _active = _pending_active;
529
530         /* we have no idea whether the plugin generated silence or not, so mark
531          * all buffers appropriately.
532          */
533
534 }
535
536 void
537 PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
538 {
539         Evoral::ControlEvent next_event (0, 0.0f);
540         framepos_t now = start;
541         framepos_t end = now + nframes;
542         framecnt_t offset = 0;
543
544         Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
545
546         if (!lm.locked()) {
547                 connect_and_run (bufs, nframes, offset, false);
548                 return;
549         }
550
551         if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
552
553                 /* no events have a time within the relevant range */
554
555                 connect_and_run (bufs, nframes, offset, true, now);
556                 return;
557         }
558
559         while (nframes) {
560
561                 framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
562
563                 connect_and_run (bufs, cnt, offset, true, now);
564
565                 nframes -= cnt;
566                 offset += cnt;
567                 now += cnt;
568
569                 if (!find_next_event (now, end, next_event)) {
570                         break;
571                 }
572         }
573
574         /* cleanup anything that is left to do */
575
576         if (nframes) {
577                 connect_and_run (bufs, nframes, offset, true, now);
578         }
579 }
580
581 float
582 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
583 {
584         if (param.type() != PluginAutomation)
585                 return 1.0;
586
587         if (_plugins.empty()) {
588                 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
589                       << endmsg;
590                 abort(); /*NOTREACHED*/
591         }
592
593         return _plugins[0]->default_value (param.id());
594 }
595
596
597 bool
598 PluginInsert::can_reset_all_parameters ()
599 {
600         bool all = true;
601         uint32_t params = 0;
602         for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
603                 bool ok=false;
604                 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
605
606                 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
607                         continue;
608                 }
609
610                 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
611                 if (!ac) {
612                         continue;
613                 }
614
615                 ++params;
616                 if (ac->automation_state() & Play) {
617                         all = false;
618                         break;
619                 }
620         }
621         return all && (params > 0);
622 }
623
624 bool
625 PluginInsert::reset_parameters_to_default ()
626 {
627         bool all = true;
628
629         for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
630                 bool ok=false;
631                 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
632
633                 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
634                         continue;
635                 }
636
637                 const float dflt = _plugins[0]->default_value (cid);
638                 const float curr = _plugins[0]->get_parameter (cid);
639
640                 if (dflt == curr) {
641                         continue;
642                 }
643
644                 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
645                 if (!ac) {
646                         continue;
647                 }
648
649                 if (ac->automation_state() & Play) {
650                         all = false;
651                         continue;
652                 }
653
654                 ac->set_value (dflt);
655         }
656         return all;
657 }
658
659 boost::shared_ptr<Plugin>
660 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
661 {
662         boost::shared_ptr<LadspaPlugin> lp;
663 #ifdef LV2_SUPPORT
664         boost::shared_ptr<LV2Plugin> lv2p;
665 #endif
666 #ifdef WINDOWS_VST_SUPPORT
667         boost::shared_ptr<WindowsVSTPlugin> vp;
668 #endif
669 #ifdef LXVST_SUPPORT
670         boost::shared_ptr<LXVSTPlugin> lxvp;
671 #endif
672 #ifdef AUDIOUNIT_SUPPORT
673         boost::shared_ptr<AUPlugin> ap;
674 #endif
675
676         if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
677                 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
678 #ifdef LV2_SUPPORT
679         } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
680                 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
681 #endif
682 #ifdef WINDOWS_VST_SUPPORT
683         } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
684                 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
685 #endif
686 #ifdef LXVST_SUPPORT
687         } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
688                 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
689 #endif
690 #ifdef AUDIOUNIT_SUPPORT
691         } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
692                 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
693 #endif
694         }
695
696         fatal << string_compose (_("programming error: %1"),
697                           X_("unknown plugin type in PluginInsert::plugin_factory"))
698               << endmsg;
699         abort(); /*NOTREACHED*/
700         return boost::shared_ptr<Plugin> ((Plugin*) 0);
701 }
702
703 bool
704 PluginInsert::configure_io (ChanCount in, ChanCount out)
705 {
706         Match old_match = _match;
707         ChanCount old_in = input_streams ();
708         ChanCount old_out = output_streams ();
709
710         _configured_in = in;
711         _configured_out = out;
712
713         /* set the matching method and number of plugins that we will use to meet this configuration */
714         _match = private_can_support_io_configuration (in, out);
715         if (set_count (_match.plugins) == false) {
716                 PluginIoReConfigure (); /* EMIT SIGNAL */
717                 return false;
718         }
719
720         /* configure plugins */
721         switch (_match.method) {
722         case Split:
723         case Hide:
724                 if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out) == false) {
725                         PluginIoReConfigure (); /* EMIT SIGNAL */
726                         return false;
727                 }
728                 break;
729
730         default:
731                 if (_plugins.front()->configure_io (in, out) == false) {
732                         PluginIoReConfigure (); /* EMIT SIGNAL */
733                         return false;
734                 }
735                 break;
736         }
737
738         if (  (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
739                         || old_in != in
740                         || old_out != out
741                         )
742         {
743                 PluginIoReConfigure (); /* EMIT SIGNAL */
744         }
745
746         // we don't know the analysis window size, so we must work with the
747         // current buffer size here. each request for data fills in these
748         // buffers and the analyser makes sure it gets enough data for the
749         // analysis window
750         session().ensure_buffer_set (_signal_analysis_inputs, in);
751         //_signal_analysis_inputs.set_count (in);
752
753         session().ensure_buffer_set (_signal_analysis_outputs, out);
754         //_signal_analysis_outputs.set_count (out);
755
756         // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
757
758         return Processor::configure_io (in, out);
759 }
760
761 /** Decide whether this PluginInsert can support a given IO configuration.
762  *  To do this, we run through a set of possible solutions in rough order of
763  *  preference.
764  *
765  *  @param in Required input channel count.
766  *  @param out Filled in with the output channel count if we return true.
767  *  @return true if the given IO configuration can be supported.
768  */
769 bool
770 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
771 {
772         return private_can_support_io_configuration (in, out).method != Impossible;
773 }
774
775 /** A private version of can_support_io_configuration which returns the method
776  *  by which the configuration can be matched, rather than just whether or not
777  *  it can be.
778  */
779 PluginInsert::Match
780 PluginInsert::private_can_support_io_configuration (ChanCount const & inx, ChanCount& out)
781 {
782         if (_plugins.empty()) {
783                 return Match();
784         }
785
786         PluginInfoPtr info = _plugins.front()->get_info();
787         ChanCount in; in += inx;
788         midi_bypass.reset();
789
790         if (info->reconfigurable_io()) {
791                 /* Plugin has flexible I/O, so delegate to it */
792                 bool const r = _plugins.front()->can_support_io_configuration (in, out);
793                 if (!r) {
794                         return Match (Impossible, 0);
795                 }
796
797                 return Match (Delegate, 1);
798         }
799
800         ChanCount inputs  = info->n_inputs;
801         ChanCount outputs = info->n_outputs;
802
803         if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
804                 DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
805                 midi_bypass.set(DataType::MIDI, 1);
806         }
807         if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
808                 DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
809                 in.set(DataType::MIDI, 0);
810         }
811
812         bool no_inputs = true;
813         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
814                 if (inputs.get (*t) != 0) {
815                         no_inputs = false;
816                         break;
817                 }
818         }
819
820         if (no_inputs) {
821                 /* no inputs so we can take any input configuration since we throw it away */
822                 out = outputs + midi_bypass;
823                 return Match (NoInputs, 1);
824         }
825
826         /* Plugin inputs match requested inputs exactly */
827         if (inputs == in) {
828                 out = outputs + midi_bypass;
829                 return Match (ExactMatch, 1);
830         }
831
832         /* We may be able to run more than one copy of the plugin within this insert
833            to cope with the insert having more inputs than the plugin.
834            We allow replication only for plugins with either zero or 1 inputs and outputs
835            for every valid data type.
836         */
837
838         uint32_t f             = 0;
839         bool     can_replicate = true;
840         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
841
842                 uint32_t nin = inputs.get (*t);
843
844                 // No inputs of this type
845                 if (nin == 0 && in.get(*t) == 0) {
846                         continue;
847                 }
848
849                 if (nin != 1 || outputs.get (*t) != 1) {
850                         can_replicate = false;
851                         break;
852                 }
853
854                 // Potential factor not set yet
855                 if (f == 0) {
856                         f = in.get(*t) / nin;
857                 }
858
859                 // Factor for this type does not match another type, can not replicate
860                 if (f != (in.get(*t) / nin)) {
861                         can_replicate = false;
862                         break;
863                 }
864         }
865
866         if (can_replicate) {
867                 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
868                         out.set (*t, outputs.get(*t) * f);
869                 }
870                 out += midi_bypass;
871                 return Match (Replicate, f);
872         }
873
874         /* If the processor has exactly one input of a given type, and
875            the plugin has more, we can feed the single processor input
876            to some or all of the plugin inputs.  This is rather
877            special-case-y, but the 1-to-many case is by far the
878            simplest.  How do I split thy 2 processor inputs to 3
879            plugin inputs?  Let me count the ways ...
880         */
881
882         bool can_split = true;
883         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
884
885                 bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
886                 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
887
888                 if (!can_split_type && !nothing_to_do_for_type) {
889                         can_split = false;
890                 }
891         }
892
893         if (can_split) {
894                 out = outputs + midi_bypass;
895                 return Match (Split, 1);
896         }
897
898         /* If the plugin has more inputs than we want, we can `hide' some of them
899            by feeding them silence.
900         */
901
902         bool could_hide = false;
903         bool cannot_hide = false;
904         ChanCount hide_channels;
905
906         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
907                 if (inputs.get(*t) > in.get(*t)) {
908                         /* there is potential to hide, since the plugin has more inputs of type t than the insert */
909                         hide_channels.set (*t, inputs.get(*t) - in.get(*t));
910                         could_hide = true;
911                 } else if (inputs.get(*t) < in.get(*t)) {
912                         /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
913                         cannot_hide = true;
914                 }
915         }
916
917         if (could_hide && !cannot_hide) {
918                 out = outputs + midi_bypass;
919                 return Match (Hide, 1, hide_channels);
920         }
921
922         midi_bypass.reset();
923         return Match (Impossible, 0);
924 }
925
926 XMLNode&
927 PluginInsert::get_state ()
928 {
929         return state (true);
930 }
931
932 XMLNode&
933 PluginInsert::state (bool full)
934 {
935         XMLNode& node = Processor::state (full);
936
937         node.add_property("type", _plugins[0]->state_node_name());
938         node.add_property("unique-id", _plugins[0]->unique_id());
939         node.add_property("count", string_compose("%1", _plugins.size()));
940
941         /* remember actual i/o configuration (for later placeholder
942          * in case the plugin goes missing) */
943         node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
944         node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
945
946         node.add_child_nocopy (_plugins[0]->get_state());
947
948         for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
949                 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
950                 if (ac) {
951                         node.add_child_nocopy (ac->get_state());
952                 }
953         }
954
955         return node;
956 }
957
958 void
959 PluginInsert::set_control_ids (const XMLNode& node, int version)
960 {
961         const XMLNodeList& nlist = node.children();
962         XMLNodeConstIterator iter;
963         set<Evoral::Parameter>::const_iterator p;
964
965         for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
966                 if ((*iter)->name() == Controllable::xml_node_name) {
967                         const XMLProperty* prop;
968
969                         if ((prop = (*iter)->property (X_("parameter"))) != 0) {
970                                 uint32_t p = atoi (prop->value());
971
972                                 /* this may create the new controllable */
973
974                                 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
975
976 #ifndef NO_PLUGIN_STATE
977                                 if (!c) {
978                                         continue;
979                                 }
980                                 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
981                                 if (ac) {
982                                         ac->set_state (**iter, version);
983                                 }
984 #endif
985                         }
986                 }
987         }
988 }
989
990 int
991 PluginInsert::set_state(const XMLNode& node, int version)
992 {
993         XMLNodeList nlist = node.children();
994         XMLNodeIterator niter;
995         XMLPropertyList plist;
996         const XMLProperty *prop;
997         ARDOUR::PluginType type;
998
999         if ((prop = node.property ("type")) == 0) {
1000                 error << _("XML node describing plugin is missing the `type' field") << endmsg;
1001                 return -1;
1002         }
1003
1004         if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1005                 type = ARDOUR::LADSPA;
1006         } else if (prop->value() == X_("lv2")) {
1007                 type = ARDOUR::LV2;
1008         } else if (prop->value() == X_("windows-vst")) {
1009                 type = ARDOUR::Windows_VST;
1010         } else if (prop->value() == X_("lxvst")) {
1011                 type = ARDOUR::LXVST;
1012         } else if (prop->value() == X_("audiounit")) {
1013                 type = ARDOUR::AudioUnit;
1014         } else {
1015                 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1016                                   prop->value())
1017                       << endmsg;
1018                 return -1;
1019         }
1020
1021         prop = node.property ("unique-id");
1022
1023         if (prop == 0) {
1024 #ifdef WINDOWS_VST_SUPPORT
1025                 /* older sessions contain VST plugins with only an "id" field.
1026                  */
1027
1028                 if (type == ARDOUR::Windows_VST) {
1029                         prop = node.property ("id");
1030                 }
1031 #endif
1032
1033 #ifdef LXVST_SUPPORT
1034                 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1035
1036                 if (type == ARDOUR::LXVST) {
1037                         prop = node.property ("id");
1038                 }
1039 #endif
1040                 /* recheck  */
1041
1042                 if (prop == 0) {
1043                         error << _("Plugin has no unique ID field") << endmsg;
1044                         return -1;
1045                 }
1046         }
1047
1048         boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
1049
1050         /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1051          * allow to move sessions windows <> linux */
1052 #ifdef LXVST_SUPPORT
1053         if (plugin == 0 && type == ARDOUR::Windows_VST) {
1054                 type = ARDOUR::LXVST;
1055                 plugin = find_plugin (_session, prop->value(), type);
1056         }
1057 #endif
1058
1059 #ifdef WINDOWS_VST_SUPPORT
1060         if (plugin == 0 && type == ARDOUR::LXVST) {
1061                 type = ARDOUR::Windows_VST;
1062                 plugin = find_plugin (_session, prop->value(), type);
1063         }
1064 #endif
1065
1066         if (plugin == 0) {
1067                 error << string_compose(
1068                         _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1069                           "Perhaps it was removed or moved since it was last used."),
1070                         prop->value())
1071                       << endmsg;
1072                 return -1;
1073         }
1074
1075         // The name of the PluginInsert comes from the plugin, nothing else
1076         _name = plugin->get_info()->name;
1077
1078         uint32_t count = 1;
1079
1080         // Processor::set_state() will set this, but too late
1081         // for it to be available when setting up plugin
1082         // state. We can't call Processor::set_state() until
1083         // the plugins themselves are created and added.
1084
1085         set_id (node);
1086
1087         if (_plugins.empty()) {
1088                 /* if we are adding the first plugin, we will need to set
1089                    up automatable controls.
1090                 */
1091                 add_plugin (plugin);
1092                 create_automatable_parameters ();
1093                 set_control_ids (node, version);
1094         }
1095
1096         if ((prop = node.property ("count")) != 0) {
1097                 sscanf (prop->value().c_str(), "%u", &count);
1098         }
1099
1100         if (_plugins.size() != count) {
1101                 for (uint32_t n = 1; n < count; ++n) {
1102                         add_plugin (plugin_factory (plugin));
1103                 }
1104         }
1105
1106         Processor::set_state (node, version);
1107
1108         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1109
1110                 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1111                    and set all plugins to the same state.
1112                 */
1113
1114                 if ((*niter)->name() == plugin->state_node_name()) {
1115
1116                         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1117                                 (*i)->set_state (**niter, version);
1118                         }
1119
1120                         break;
1121                 }
1122         }
1123
1124         if (version < 3000) {
1125
1126                 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1127                    this is all handled by Automatable
1128                 */
1129
1130                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1131                         if ((*niter)->name() == "Redirect") {
1132                                 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1133                                 Processor::set_state (**niter, version);
1134                                 break;
1135                         }
1136                 }
1137
1138                 set_parameter_state_2X (node, version);
1139         }
1140
1141         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1142                 if (active()) {
1143                         (*i)->activate ();
1144                 } else {
1145                         (*i)->deactivate ();
1146                 }
1147         }
1148
1149         return 0;
1150 }
1151
1152 void
1153 PluginInsert::update_id (PBD::ID id)
1154 {
1155         set_id (id.to_s());
1156         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1157                 (*i)->set_insert_id (id);
1158         }
1159 }
1160
1161 void
1162 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
1163 {
1164         XMLNodeList nlist = node.children();
1165         XMLNodeIterator niter;
1166
1167         /* look for port automation node */
1168
1169         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1170
1171                 if ((*niter)->name() != port_automation_node_name) {
1172                         continue;
1173                 }
1174
1175                 XMLNodeList cnodes;
1176                 XMLProperty *cprop;
1177                 XMLNodeConstIterator iter;
1178                 XMLNode *child;
1179                 const char *port;
1180                 uint32_t port_id;
1181
1182                 cnodes = (*niter)->children ("port");
1183
1184                 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1185
1186                         child = *iter;
1187
1188                         if ((cprop = child->property("number")) != 0) {
1189                                 port = cprop->value().c_str();
1190                         } else {
1191                                 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1192                                 continue;
1193                         }
1194
1195                         sscanf (port, "%" PRIu32, &port_id);
1196
1197                         if (port_id >= _plugins[0]->parameter_count()) {
1198                                 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1199                                 continue;
1200                         }
1201
1202                         boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
1203                                         control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1204
1205                         if (c && c->alist()) {
1206                                 if (!child->children().empty()) {
1207                                         c->alist()->set_state (*child->children().front(), version);
1208
1209                                         /* In some cases 2.X saves lists with min_yval and max_yval
1210                                            being FLT_MIN and FLT_MAX respectively.  This causes problems
1211                                            in A3 because these min/max values are used to compute
1212                                            where GUI control points should be drawn.  If we see such
1213                                            values, `correct' them to the min/max of the appropriate
1214                                            parameter.
1215                                         */
1216
1217                                         float min_y = c->alist()->get_min_y ();
1218                                         float max_y = c->alist()->get_max_y ();
1219
1220                                         ParameterDescriptor desc;
1221                                         _plugins.front()->get_parameter_descriptor (port_id, desc);
1222
1223                                         if (min_y == FLT_MIN) {
1224                                                 min_y = desc.lower;
1225                                         }
1226
1227                                         if (max_y == FLT_MAX) {
1228                                                 max_y = desc.upper;
1229                                         }
1230
1231                                         c->alist()->set_yrange (min_y, max_y);
1232                                 }
1233                         } else {
1234                                 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1235                         }
1236                 }
1237
1238                 /* done */
1239
1240                 break;
1241         }
1242 }
1243
1244
1245 string
1246 PluginInsert::describe_parameter (Evoral::Parameter param)
1247 {
1248         if (param.type() == PluginAutomation) {
1249                 return _plugins[0]->describe_parameter (param);
1250         } else if (param.type() == PluginPropertyAutomation) {
1251                 boost::shared_ptr<AutomationControl> c(automation_control(param));
1252                 if (c && !c->desc().label.empty()) {
1253                         return c->desc().label;
1254                 }
1255         }
1256         return Automatable::describe_parameter(param);
1257 }
1258
1259 ARDOUR::framecnt_t
1260 PluginInsert::signal_latency() const
1261 {
1262         if (_user_latency) {
1263                 return _user_latency;
1264         }
1265
1266         return _plugins[0]->signal_latency ();
1267 }
1268
1269 ARDOUR::PluginType
1270 PluginInsert::type ()
1271 {
1272        return plugin()->get_info()->type;
1273 }
1274
1275 PluginInsert::PluginControl::PluginControl (PluginInsert*                     p,
1276                                             const Evoral::Parameter&          param,
1277                                             const ParameterDescriptor&        desc,
1278                                             boost::shared_ptr<AutomationList> list)
1279         : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1280         , _plugin (p)
1281 {
1282         if (alist()) {
1283                 alist()->reset_default (desc.normal);
1284                 if (desc.toggled) {
1285                         list->set_interpolation(Evoral::ControlList::Discrete);
1286                 }
1287         }
1288
1289         if (desc.toggled) {
1290                 set_flags(Controllable::Toggle);
1291         }
1292 }
1293
1294 /** @param val `user' value */
1295 void
1296 PluginInsert::PluginControl::set_value (double user_val)
1297 {
1298         /* FIXME: probably should be taking out some lock here.. */
1299
1300         for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1301                 (*i)->set_parameter (_list->parameter().id(), user_val);
1302         }
1303
1304         boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1305         if (iasp) {
1306                 iasp->set_parameter (_list->parameter().id(), user_val);
1307         }
1308
1309         AutomationControl::set_value (user_val);
1310 }
1311
1312 void
1313 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
1314 {
1315         AutomationControl::set_value (user_val);
1316 }
1317
1318 XMLNode&
1319 PluginInsert::PluginControl::get_state ()
1320 {
1321         stringstream ss;
1322
1323         XMLNode& node (AutomationControl::get_state());
1324         ss << parameter().id();
1325         node.add_property (X_("parameter"), ss.str());
1326
1327         return node;
1328 }
1329
1330 /** @return `user' val */
1331 double
1332 PluginInsert::PluginControl::get_value () const
1333 {
1334         boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
1335
1336         if (!plugin) {
1337                 return 0.0;
1338         }
1339
1340         return plugin->get_parameter (_list->parameter().id());
1341 }
1342
1343 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert*                     p,
1344                                                             const Evoral::Parameter&          param,
1345                                                             const ParameterDescriptor&        desc,
1346                                                             boost::shared_ptr<AutomationList> list)
1347         : AutomationControl (p->session(), param, desc, list)
1348         , _plugin (p)
1349 {
1350         if (alist()) {
1351                 alist()->set_yrange (desc.lower, desc.upper);
1352                 alist()->reset_default (desc.normal);
1353         }
1354
1355         if (desc.toggled) {
1356                 set_flags(Controllable::Toggle);
1357         }
1358 }
1359
1360 void
1361 PluginInsert::PluginPropertyControl::set_value (double user_val)
1362 {
1363         /* Old numeric set_value(), coerce to appropriate datatype if possible.
1364            This is lossy, but better than nothing until Ardour's automation system
1365            can handle various datatypes all the way down. */
1366         const Variant value(_desc.datatype, user_val);
1367         if (value.type() == Variant::NOTHING) {
1368                 error << "set_value(double) called for non-numeric property" << endmsg;
1369                 return;
1370         }
1371
1372         for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1373                 (*i)->set_property(_list->parameter().id(), value);
1374         }
1375
1376         _value = value;
1377         AutomationControl::set_value(user_val);
1378 }
1379
1380 XMLNode&
1381 PluginInsert::PluginPropertyControl::get_state ()
1382 {
1383         stringstream ss;
1384
1385         XMLNode& node (AutomationControl::get_state());
1386         ss << parameter().id();
1387         node.add_property (X_("property"), ss.str());
1388         node.remove_property (X_("value"));
1389
1390         return node;
1391 }
1392
1393 double
1394 PluginInsert::PluginPropertyControl::get_value () const
1395 {
1396         return _value.to_double();
1397 }
1398
1399 boost::shared_ptr<Plugin>
1400 PluginInsert::get_impulse_analysis_plugin()
1401 {
1402         boost::shared_ptr<Plugin> ret;
1403         if (_impulseAnalysisPlugin.expired()) {
1404                 ret = plugin_factory(_plugins[0]);
1405                 ret->configure_io (input_streams (), output_streams ());
1406                 _impulseAnalysisPlugin = ret;
1407         } else {
1408                 ret = _impulseAnalysisPlugin.lock();
1409         }
1410
1411         return ret;
1412 }
1413
1414 void
1415 PluginInsert::collect_signal_for_analysis (framecnt_t nframes)
1416 {
1417         // called from outside the audio thread, so this should be safe
1418         // only do audio as analysis is (currently) only for audio plugins
1419         _signal_analysis_inputs.ensure_buffers(  DataType::AUDIO, input_streams().n_audio(),  nframes);
1420         _signal_analysis_outputs.ensure_buffers( DataType::AUDIO, output_streams().n_audio(), nframes);
1421
1422         _signal_analysis_collected_nframes   = 0;
1423         _signal_analysis_collect_nframes_max = nframes;
1424 }
1425
1426 /** Add a plugin to our list */
1427 void
1428 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
1429 {
1430         plugin->set_insert_id (this->id());
1431
1432         if (_plugins.empty()) {
1433                 /* first (and probably only) plugin instance - connect to relevant signals
1434                  */
1435
1436                 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
1437                 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1438                 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1439         }
1440
1441         _plugins.push_back (plugin);
1442 }
1443
1444 void
1445 PluginInsert::realtime_handle_transport_stopped ()
1446 {
1447         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1448                 (*i)->realtime_handle_transport_stopped ();
1449         }
1450 }
1451
1452 void
1453 PluginInsert::realtime_locate ()
1454 {
1455         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1456                 (*i)->realtime_locate ();
1457         }
1458 }
1459
1460 void
1461 PluginInsert::monitoring_changed ()
1462 {
1463         for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1464                 (*i)->monitoring_changed ();
1465         }
1466 }
1467
1468 void
1469 PluginInsert::start_touch (uint32_t param_id)
1470 {
1471         boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1472         if (ac) {
1473                 ac->start_touch (session().audible_frame());
1474         }
1475 }
1476
1477 void
1478 PluginInsert::end_touch (uint32_t param_id)
1479 {
1480         boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
1481         if (ac) {
1482                 ac->stop_touch (true, session().audible_frame());
1483         }
1484 }