PluginInfo::type added to copy constructor. But why is the copy constructor defined...
[ardour.git] / libs / ardour / 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 #include <string>
21
22 #include <sigc++/bind.h>
23
24 #include <pbd/failed_constructor.h>
25 #include <pbd/xml++.h>
26 #include <pbd/stacktrace.h>
27
28 #include <ardour/insert.h>
29 #include <ardour/mtdm.h>
30 #include <ardour/plugin.h>
31 #include <ardour/port.h>
32 #include <ardour/route.h>
33 #include <ardour/ladspa_plugin.h>
34
35 #ifdef HAVE_SLV2
36 #include <ardour/lv2_plugin.h>
37 #endif
38
39 #ifdef VST_SUPPORT
40 #include <ardour/vst_plugin.h>
41 #endif
42
43 #ifdef HAVE_AUDIOUNITS
44 #include <ardour/audio_unit.h>
45 #endif
46
47 #include <ardour/audioengine.h>
48 #include <ardour/session.h>
49 #include <ardour/types.h>
50
51 #include "i18n.h"
52
53 using namespace std;
54 using namespace ARDOUR;
55 using namespace PBD;
56
57 Insert::Insert(Session& s, string name, Placement p)
58         : Redirect (s, name, p)
59 {
60 }
61
62 Insert::Insert(Session& s, string name, Placement p, int imin, int imax, int omin, int omax)
63         : Redirect (s, name, p, imin, imax, omin, omax)
64 {
65 }
66
67 /***************************************************************
68  Plugin inserts: send data through a plugin
69  ***************************************************************/
70
71 const string PluginInsert::port_automation_node_name = "PortAutomation";
72
73 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placement placement)
74         : Insert (s, plug->name(), placement)
75 {
76         /* the first is the master */
77
78         _plugins.push_back (plug);
79
80         _plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
81         
82         init ();
83
84         RedirectCreated (this); /* EMIT SIGNAL */
85 }
86
87 PluginInsert::PluginInsert (Session& s, const XMLNode& node)
88         : Insert (s, "will change", PreFader)
89 {
90         if (set_state (node)) {
91                 throw failed_constructor();
92         }
93
94         _plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
95 }
96
97 PluginInsert::PluginInsert (const PluginInsert& other)
98         : Insert (other._session, other.plugin()->name(), other.placement())
99 {
100         uint32_t count = other._plugins.size();
101
102         /* make as many copies as requested */
103         for (uint32_t n = 0; n < count; ++n) {
104                 _plugins.push_back (plugin_factory (other.plugin (n)));
105         }
106
107
108         _plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
109
110         init ();
111
112         RedirectCreated (this); /* EMIT SIGNAL */
113 }
114
115 int
116 PluginInsert::set_count (uint32_t num)
117 {
118         bool require_state = !_plugins.empty();
119
120         /* this is a bad idea.... we shouldn't do this while active.
121            only a route holding their redirect_lock should be calling this 
122         */
123
124         if (num == 0) { 
125                 return -1;
126         } else if (num > _plugins.size()) {
127                 uint32_t diff = num - _plugins.size();
128
129                 for (uint32_t n = 0; n < diff; ++n) {
130                         _plugins.push_back (plugin_factory (_plugins[0]));
131
132                         if (require_state) {
133                                 /* XXX do something */
134                         }
135                 }
136
137         } else if (num < _plugins.size()) {
138                 uint32_t diff = _plugins.size() - num;
139                 for (uint32_t n= 0; n < diff; ++n) {
140                         _plugins.pop_back();
141                 }
142         }
143
144         return 0;
145 }
146
147 void
148 PluginInsert::init ()
149 {
150         set_automatable ();
151 }
152
153 PluginInsert::~PluginInsert ()
154 {
155         GoingAway (); /* EMIT SIGNAL */
156 }
157
158 void
159 PluginInsert::automation_list_creation_callback (uint32_t which, AutomationList& alist)
160 {
161         alist.automation_state_changed.connect (sigc::bind (mem_fun (*this, &PluginInsert::auto_state_changed), (which)));
162 }
163
164 void
165 PluginInsert::auto_state_changed (uint32_t which)
166 {
167         AutomationList& alist (automation_list (which));
168
169         if (alist.automation_state() != Off) {
170                 _plugins[0]->set_parameter (which, alist.eval (_session.transport_frame()));
171         }
172 }
173
174 uint32_t
175 PluginInsert::output_streams() const
176 {
177         int32_t out = _plugins[0]->get_info()->n_outputs;
178
179         if (out < 0) {
180                 return _plugins[0]->output_streams ();
181         } else {
182                 return out * _plugins.size();
183         }
184 }
185
186 uint32_t
187 PluginInsert::input_streams() const
188 {
189         int32_t in = _plugins[0]->get_info()->n_inputs;
190
191         if (in < 0) {
192                 return _plugins[0]->input_streams ();
193         } else {
194                 return in * _plugins.size();
195         }
196 }
197
198 uint32_t
199 PluginInsert::natural_output_streams() const
200 {
201         return _plugins[0]->get_info()->n_outputs;
202 }
203
204 uint32_t
205 PluginInsert::natural_input_streams() const
206 {
207         return _plugins[0]->get_info()->n_inputs;
208 }
209
210 bool
211 PluginInsert::is_generator() const
212 {
213         /* XXX more finesse is possible here. VST plugins have a
214            a specific "instrument" flag, for example.
215          */
216
217         return _plugins[0]->get_info()->n_inputs == 0;
218 }
219
220 void
221 PluginInsert::set_automatable ()
222 {
223         /* fill the parameter automation list with null AutomationLists */
224
225         parameter_automation.assign (_plugins.front()->parameter_count(), (AutomationList*) 0);
226
227         set<uint32_t> a;
228         
229         a = _plugins.front()->automatable ();
230
231         for (set<uint32_t>::iterator i = a.begin(); i != a.end(); ++i) {
232                 can_automate (*i);
233         }
234 }
235
236 void
237 PluginInsert::parameter_changed (uint32_t which, float val)
238 {
239         vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin();
240
241         /* don't set the first plugin, just all the slaves */
242
243         if (i != _plugins.end()) {
244                 ++i;
245                 for (; i != _plugins.end(); ++i) {
246                         (*i)->set_parameter (which, val);
247                 }
248         }
249 }
250
251 void
252 PluginInsert::set_block_size (nframes_t nframes)
253 {
254         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
255                 (*i)->set_block_size (nframes);
256         }
257 }
258
259 void
260 PluginInsert::activate ()
261 {
262         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
263                 (*i)->activate ();
264         }
265 }
266
267 void
268 PluginInsert::deactivate ()
269 {
270         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
271                 (*i)->deactivate ();
272         }
273 }
274
275 void
276 PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now)
277 {
278         int32_t in_index = 0;
279         int32_t out_index = 0;
280
281         /* Note that we've already required that plugins
282            be able to handle in-place processing.
283         */
284
285         // cerr << "Connect and run for " << _plugins[0]->name() << " auto ? " << with_auto << " nf = " << nframes << " off = " << offset << endl;
286         
287         if (with_auto) {
288
289                 vector<AutomationList*>::iterator li;
290                 uint32_t n;
291                 
292                 for (n = 0, li = parameter_automation.begin(); li != parameter_automation.end(); ++li, ++n) {
293                         
294                         AutomationList* alist = *li;
295
296                         if (alist && alist->automation_playback()) {
297                                 bool valid;
298                                 
299                                 float val = alist->rt_safe_eval (now, valid);                           
300
301                                 if (valid) {
302                                         /* set the first plugin, the others will be set via signals */
303                                         // cerr << "\t@ " << now << " param[" << n << "] = " << val << endl;
304                                         _plugins[0]->set_parameter (n, val);
305                                 }
306
307                         } 
308                 }
309         } 
310
311         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
312                 (*i)->connect_and_run (bufs, nbufs, in_index, out_index, nframes, offset);
313         }
314 }
315
316 void
317 PluginInsert::automation_snapshot (nframes_t now, bool force)
318 {
319         vector<AutomationList*>::iterator li;
320         uint32_t n;
321
322         for (n = 0, li = parameter_automation.begin(); li != parameter_automation.end(); ++li, ++n) {
323                 
324                 AutomationList *alist = *li;
325
326                 if (alist && alist->automation_write ()) {
327                         
328                         float val = _plugins[0]->get_parameter (n);
329                         alist->rt_add (now, val);
330                         last_automation_snapshot = now;
331                 }
332         }
333 }
334
335 void
336 PluginInsert::transport_stopped (nframes_t now)
337 {
338         vector<AutomationList*>::iterator li;
339         uint32_t n;
340
341         for (n = 0, li = parameter_automation.begin(); li != parameter_automation.end(); ++li, ++n) {
342
343                 AutomationList* alist = *li;
344
345                 if (alist) {
346                         alist->reposition_for_rt_add (now);
347                         if (alist->automation_state() != Off) {
348                                 _plugins[0]->set_parameter (n, alist->eval (now));
349                         }
350                 }
351         }
352 }
353
354 void
355 PluginInsert::silence (nframes_t nframes)
356 {
357         int32_t in_index = 0;
358         int32_t out_index = 0;
359         int32_t n;
360
361         if (active()) {
362                 for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
363                         n = input_streams();
364                         (*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, 0);
365                 }
366         }
367 }
368         
369 void
370 PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
371 {
372         if (active()) {
373
374                 if (_session.transport_rolling()) {
375                         automation_run (bufs, nbufs, nframes);
376                 } else {
377                         connect_and_run (bufs, nbufs, nframes, 0, false);
378                 }
379
380         } else {
381
382                 uint32_t in = input_streams ();
383                 uint32_t out = output_streams ();
384
385                 if (out > in) {
386                         
387                         /* not active, but something has make up for any channel count increase,
388                            so copy the last buffer to the extras.
389                         */
390                         
391                         for (uint32_t n = out - in; n < out && n < nbufs; ++n) {
392                                 memcpy (bufs[n], bufs[in - 1], sizeof (Sample) * nframes);
393                         }
394                 }
395         }
396 }
397
398 void
399 PluginInsert::set_parameter (uint32_t port, float val)
400 {
401         /* the others will be set from the event triggered by this */
402
403         float last_val = _plugins[0]->get_parameter (port);
404         Plugin::ParameterDescriptor desc;
405         _plugins[0]->get_parameter_descriptor(port, desc);
406         
407         _plugins[0]->set_parameter (port, val);
408         
409         if (automation_list (port).automation_write()) {
410                 if ( desc.toggled )  //store the previous value just before this so any interpolation works right 
411                         automation_list (port).add (_session.audible_frame()-1, last_val);
412                 automation_list (port).add (_session.audible_frame(), val);
413         }
414
415         _session.set_dirty();
416 }
417
418 void
419 PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
420 {
421         ControlEvent next_event (0, 0.0f);
422         nframes_t now = _session.transport_frame ();
423         nframes_t end = now + nframes;
424         nframes_t offset = 0;
425
426         Glib::Mutex::Lock lm (_automation_lock, Glib::TRY_LOCK);
427
428         if (!lm.locked()) {
429                 connect_and_run (bufs, nbufs, nframes, 0, false, now);
430                 return;
431         }
432
433         if (!find_next_event (now, end, next_event)) {
434                 /* no events have a time within the relevant range */
435                 connect_and_run (bufs, nbufs, nframes, 0, true, now);
436                 return;
437         }
438
439         while (nframes) {
440                 nframes_t cnt = min (((nframes_t) ceil (next_event.when) - now), nframes);
441
442                 connect_and_run (bufs, nbufs, cnt, offset, true, now);
443                 
444                 nframes -= cnt;
445                 now += cnt;
446                 offset += cnt;
447
448                 if (!find_next_event (now, end, next_event)) {
449                         break;
450                 }
451         }
452             
453         /* cleanup anything that is left to do */
454   
455         if (nframes) {
456                 connect_and_run (bufs, nbufs, nframes, offset, true, now);
457         }
458
459 }       
460
461 float
462 PluginInsert::default_parameter_value (uint32_t port)
463 {
464         if (_plugins.empty()) {
465                 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
466                       << endmsg;
467                 /*NOTREACHED*/
468         }
469
470         return _plugins[0]->default_value (port);
471 }
472         
473 void
474 PluginInsert::set_port_automation_state (uint32_t port, AutoState s)
475 {
476         if (port < _plugins[0]->parameter_count()) {
477                 
478                 AutomationList& al = automation_list (port);
479
480                 if (s != al.automation_state()) {
481                         al.set_automation_state (s);
482                         _session.set_dirty ();
483                 }
484         }
485 }
486
487 AutoState
488 PluginInsert::get_port_automation_state (uint32_t port)
489 {
490         if (port < _plugins[0]->parameter_count()) {
491                 return automation_list (port).automation_state();
492         } else {
493                 return Off;
494         }
495 }
496
497 void
498 PluginInsert::protect_automation ()
499 {
500         set<uint32_t> automated_params;
501
502         what_has_automation (automated_params);
503
504         for (set<uint32_t>::iterator i = automated_params.begin(); i != automated_params.end(); ++i) {
505
506                 AutomationList& al = automation_list (*i);
507
508                 switch (al.automation_state()) {
509                 case Write:
510                         al.set_automation_state (Off);
511                         break;
512                 case Touch:
513                         al.set_automation_state (Play);
514                         break;
515                 default:
516                         break;
517                 }
518         }
519 }
520
521 boost::shared_ptr<Plugin>
522 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
523 {
524         boost::shared_ptr<LadspaPlugin> lp;
525 #ifdef HAVE_SLV2
526         boost::shared_ptr<LV2Plugin> lv2p;
527 #endif
528 #ifdef VST_SUPPORT
529         boost::shared_ptr<VSTPlugin> vp;
530 #endif
531 #ifdef HAVE_AUDIOUNITS
532         boost::shared_ptr<AUPlugin> ap;
533 #endif
534
535         if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
536                 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
537 #ifdef HAVE_SLV2
538         } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
539                 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
540 #endif
541 #ifdef VST_SUPPORT
542         } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
543                 return boost::shared_ptr<Plugin> (new VSTPlugin (*vp));
544 #endif
545 #ifdef HAVE_AUDIOUNITS
546         } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
547                 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
548 #endif
549         }
550
551         fatal << string_compose (_("programming error: %1"),
552                           X_("unknown plugin type in PluginInsert::plugin_factory"))
553               << endmsg;
554         /*NOTREACHED*/
555         return boost::shared_ptr<Plugin> ((Plugin*) 0);
556 }
557
558 int32_t
559 PluginInsert::configure_io (int32_t magic, int32_t in, int32_t out)
560 {
561         int32_t ret;
562
563         if ((ret = set_count (magic)) < 0) {
564                 return ret;
565         }
566
567         /* if we're running replicated plugins, each plugin has
568            the same i/o configuration and we may need to announce how many
569            output streams there are.
570
571            if we running a single plugin, we need to configure it.
572         */
573
574         return _plugins[0]->configure_io (in, out);
575 }
576
577 int32_t 
578 PluginInsert::can_do (int32_t in, int32_t& out)
579 {
580         return _plugins[0]->can_do (in, out);
581 }
582
583 XMLNode&
584 PluginInsert::get_state(void)
585 {
586         return state (true);
587 }
588
589 XMLNode&
590 PluginInsert::state (bool full)
591 {
592         char buf[256];
593         XMLNode *node = new XMLNode("Insert");
594
595         node->add_child_nocopy (Redirect::state (full));
596
597         node->add_property ("type", _plugins[0]->state_node_name());
598         node->add_property("unique-id", _plugins[0]->unique_id());
599         node->add_property("count", string_compose("%1", _plugins.size()));
600         node->add_child_nocopy (_plugins[0]->get_state());
601
602         /* add controllables */
603
604         XMLNode* control_node = new XMLNode (X_("controls"));
605
606         for (uint32_t x = 0; x < _plugins[0]->parameter_count(); ++x) {
607                 Controllable* c = _plugins[0]->get_nth_control (x, true);
608                 if (c) {
609                         XMLNode& controllable_state (c->get_state());
610                         controllable_state.add_property ("parameter", to_string (x, std::dec));
611                         control_node->add_child_nocopy (controllable_state);
612                 }
613         }
614         node->add_child_nocopy (*control_node);
615
616         /* add port automation state */
617         XMLNode *autonode = new XMLNode(port_automation_node_name);
618         set<uint32_t> automatable = _plugins[0]->automatable();
619
620         for (set<uint32_t>::iterator x =  automatable.begin(); x != automatable.end(); ++x) {
621
622                 XMLNode* child = new XMLNode("port");
623                 snprintf(buf, sizeof(buf), "%" PRIu32, *x);
624                 child->add_property("number", string(buf));
625
626 #ifdef HAVE_SLV2
627                 LV2Plugin* lv2p = dynamic_cast<LV2Plugin*>(_plugins[0].get());
628                 if (lv2p) {
629                         child->add_property("symbol", string(lv2p->port_symbol(*x)));
630                 }
631 #endif
632
633                 child->add_child_nocopy (automation_list (*x).state (full));
634                 autonode->add_child_nocopy (*child);
635         }
636
637         node->add_child_nocopy (*autonode);
638         
639         return *node;
640 }
641
642 int
643 PluginInsert::set_state(const XMLNode& node)
644 {
645         XMLNodeList nlist = node.children();
646         XMLNodeIterator niter;
647         XMLPropertyList plist;
648         const XMLProperty *prop;
649         ARDOUR::PluginType type;
650
651         if ((prop = node.property ("type")) == 0) {
652                 error << _("XML node describing insert is missing the `type' field") << endmsg;
653                 return -1;
654         }
655
656         if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
657                 type = ARDOUR::LADSPA;
658         } else if (prop->value() == X_("lv2")) {
659                 type = ARDOUR::LV2;
660         } else if (prop->value() == X_("vst")) {
661                 type = ARDOUR::VST;
662         } else if (prop->value() == X_("audiounit")) {
663                 type = ARDOUR::AudioUnit;
664         } else {
665                 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
666                                   prop->value())
667                       << endmsg;
668                 return -1;
669         }
670
671         prop = node.property ("unique-id");
672         if (prop == 0) {
673 #ifdef VST_SUPPORT
674                 /* older sessions contain VST plugins with only an "id" field.
675                  */
676                 
677                 if (type == ARDOUR::VST) {
678                         prop = node.property ("id");
679                 }
680 #endif          
681                 /* recheck  */
682
683                 if (prop == 0) {
684                         error << _("Plugin has no unique ID field") << endmsg;
685                         return -1;
686                 }
687         }
688
689         boost::shared_ptr<Plugin> plugin;
690
691         plugin = find_plugin (_session, prop->value(), type);   
692
693         if (plugin == 0) {
694                 error << string_compose(_("Found a reference to a plugin (\"%1\") that is unknown.\n"
695                                    "Perhaps it was removed or moved since it was last used."), prop->value()) 
696                       << endmsg;
697                 return -1;
698         }
699
700         uint32_t count = 1;
701
702         if ((prop = node.property ("count")) != 0) {
703                 sscanf (prop->value().c_str(), "%u", &count);
704         }
705
706         if (_plugins.size() != count) {
707                 
708                 _plugins.push_back (plugin);
709                 
710                 for (uint32_t n=1; n < count; ++n) {
711                         _plugins.push_back (plugin_factory (plugin));
712                 }
713         }
714
715         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
716                 if ((*niter)->name() == plugin->state_node_name()) {
717                         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
718                                 (*i)->set_state (**niter);
719                         }
720                         break;
721                 }
722         } 
723
724         if (niter == nlist.end()) {
725                 error << string_compose(_("XML node describing a plugin insert is missing the `%1' information"), plugin->state_node_name()) << endmsg;
726                 return -1;
727         }
728
729         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
730                 if ((*niter)->name() == Redirect::state_node_name) {
731                         Redirect::set_state (**niter);
732                         break;
733                 }
734         }
735
736         if (niter == nlist.end()) {
737                 error << _("XML node describing insert is missing a Redirect node") << endmsg;
738                 return -1;
739         }
740
741         /* look for controllables node */
742         
743         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
744
745                 if ((*niter)->name() != X_("controls")) {
746                         continue;
747                 }
748                 
749                 XMLNodeList grandchildren ((*niter)->children());
750                 XMLProperty* prop;
751                 XMLNodeIterator gciter;
752                 uint32_t param;
753                 
754                 for (gciter = grandchildren.begin(); gciter != grandchildren.end(); ++gciter) {
755                         if ((prop = (*gciter)->property (X_("parameter"))) != 0) {
756                                 param = atoi (prop->value());
757                                 /* force creation of controllable for this parameter */
758                                 _plugins[0]->make_nth_control (param, **gciter);
759                         } 
760                 }
761
762                 break;
763         }
764                 
765         set_automatable ();
766         
767         /* look for port automation node */
768         
769         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
770
771                 if ((*niter)->name() != port_automation_node_name) {
772                         continue;
773                 }
774
775                 XMLNodeList cnodes;
776                 XMLProperty *cprop;
777                 XMLNodeConstIterator iter;
778                 XMLNode *child;
779                 const char *port;
780                 uint32_t port_id;
781                 
782                 cnodes = (*niter)->children ("port");
783                 
784                 for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
785                         
786                         child = *iter;
787                         
788                         if ((cprop = child->property("number")) != 0) {
789                                 port = cprop->value().c_str();
790                         } else {
791                                 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
792                                 continue;
793                         }
794                         
795                         sscanf (port, "%" PRIu32, &port_id);
796                         
797                         if (port_id >= _plugins[0]->parameter_count()) {
798                                 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
799                                 continue;
800                         }
801
802                         if (!child->children().empty()) {
803                                 automation_list (port_id).set_state (*child->children().front());
804                         } else {
805                                 if ((cprop = child->property("auto")) != 0) {
806                                         
807                                         /* old school */
808
809                                         int x;
810                                         sscanf (cprop->value().c_str(), "0x%x", &x);
811                                         automation_list (port_id).set_automation_state (AutoState (x));
812
813                                 } else {
814                                         
815                                         /* missing */
816                                         
817                                         automation_list (port_id).set_automation_state (Off);
818                                 }
819                         }
820
821                 }
822
823                 /* done */
824
825                 break;
826         } 
827
828         if (niter == nlist.end()) {
829                 warning << string_compose(_("XML node describing a port automation is missing the `%1' information"), port_automation_node_name) << endmsg;
830         }
831         
832         // The name of the PluginInsert comes from the plugin, nothing else
833         set_name(plugin->get_info()->name,this);
834         
835         return 0;
836 }
837
838 string
839 PluginInsert::describe_parameter (uint32_t what)
840 {
841         return _plugins[0]->describe_parameter (what);
842 }
843
844 nframes_t 
845 PluginInsert::latency() 
846 {
847         return _plugins[0]->latency ();
848 }
849         
850 ARDOUR::PluginType
851 PluginInsert::type ()
852 {
853         return plugin()->get_info()->type;
854 }
855
856 /***************************************************************
857  Port inserts: send output to a port, pick up input at a port
858  ***************************************************************/
859
860 PortInsert::PortInsert (Session& s, Placement p)
861         : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
862 {
863         init ();
864         RedirectCreated (this); /* EMIT SIGNAL */
865
866 }
867
868 PortInsert::PortInsert (const PortInsert& other)
869         : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
870 {
871         init ();
872         RedirectCreated (this); /* EMIT SIGNAL */
873 }
874
875 void
876 PortInsert::init ()
877 {
878         _mtdm = 0;
879         _latency_detect = false;
880         _latency_flush_frames = false;
881         _measured_latency = 0;
882 }
883
884 PortInsert::PortInsert (Session& s, const XMLNode& node)
885         : Insert (s, "will change", PreFader)
886 {
887         init ();
888
889         bitslot = 0xffffffff;
890
891         if (set_state (node)) {
892                 throw failed_constructor();
893         }
894
895         RedirectCreated (this); /* EMIT SIGNAL */
896 }
897
898 PortInsert::~PortInsert ()
899 {
900         delete _mtdm;
901         GoingAway ();
902 }
903
904 void
905 PortInsert::start_latency_detection ()
906 {
907         if (_mtdm != 0) {
908                 delete _mtdm;
909         }
910
911         _mtdm = new MTDM;
912         _latency_flush_frames = false;
913         _latency_detect = true;
914         _measured_latency = 0;
915 }
916
917 void
918 PortInsert::stop_latency_detection ()
919 {
920         _latency_flush_frames = latency() + _session.engine().frames_per_cycle();
921         _latency_detect = false;
922 }
923
924 void
925 PortInsert::set_measured_latency (nframes_t n)
926 {
927         _measured_latency = n;
928 }
929
930 void
931 PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
932 {
933         if (n_outputs() == 0) {
934                 return;
935         }
936
937         vector<Port*>::iterator o;
938
939         if (_latency_detect) {
940
941                 if (n_inputs() != 0) {
942                         Sample* in = get_input_buffer (0, nframes);
943                         Sample* out = get_output_buffer (0, nframes);
944
945                         _mtdm->process (nframes, in, out);
946                         
947                         for (o = _outputs.begin(); o != _outputs.end(); ++o) {
948                                 (*o)->mark_silence (false);
949                         }
950                 }
951
952                 return;
953
954         } else if (_latency_flush_frames) {
955
956                 /* wait for the entire input buffer to drain before picking up input again so that we can't
957                    hear the remnants of whatever MTDM pumped into the pipeline.
958                 */
959
960                 silence (nframes);
961
962                 if (_latency_flush_frames > nframes) {
963                         _latency_flush_frames -= nframes;
964                 } else {
965                         _latency_flush_frames = 0;
966                 }
967
968                 return;
969         }
970
971         if (!active()) {
972                 /* deliver silence */
973                 silence (nframes);
974                 return;
975         }
976
977         /* deliver output */
978
979         uint32_t n;
980
981         for (o = _outputs.begin(), n = 0; o != _outputs.end(); ++o, ++n) {
982                 memcpy (get_output_buffer (n, nframes), bufs[min(nbufs,n)], sizeof (Sample) * nframes);
983                 (*o)->mark_silence (false);
984         }
985         
986         vector<Port*>::iterator i;
987
988         /* collect input */
989         
990         for (i = _inputs.begin(), n = 0; i != _inputs.end(); ++i, ++n) {
991                 memcpy (bufs[min(nbufs,n)], get_input_buffer (n, nframes), sizeof (Sample) * nframes);
992         }
993 }
994
995 XMLNode&
996 PortInsert::get_state(void)
997 {
998         return state (true);
999 }
1000
1001 XMLNode&
1002 PortInsert::state (bool full)
1003 {
1004         XMLNode *node = new XMLNode("Insert");
1005         char buf[32];
1006         node->add_child_nocopy (Redirect::state(full)); 
1007         node->add_property ("type", "port");
1008         snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
1009         node->add_property ("bitslot", buf);
1010
1011         return *node;
1012 }
1013
1014 int
1015 PortInsert::set_state(const XMLNode& node)
1016 {
1017         XMLNodeList nlist = node.children();
1018         XMLNodeIterator niter;
1019         XMLPropertyList plist;
1020         const XMLProperty *prop;
1021
1022         if ((prop = node.property ("type")) == 0) {
1023                 error << _("XML node describing insert is missing the `type' field") << endmsg;
1024                 return -1;
1025         }
1026         
1027         if (prop->value() != "port") {
1028                 error << _("non-port insert XML used for port plugin insert") << endmsg;
1029                 return -1;
1030         }
1031
1032         if ((prop = node.property ("bitslot")) == 0) {
1033                 bitslot = _session.next_insert_id();
1034         } else {
1035                 uint32_t old_bitslot = bitslot;
1036                 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
1037
1038                 if (old_bitslot != bitslot) {
1039                         _session.mark_insert_id (bitslot);
1040                 }
1041         }
1042
1043         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1044                 if ((*niter)->name() == Redirect::state_node_name) {
1045                         Redirect::set_state (**niter);
1046                         break;
1047                 }
1048         }
1049
1050         if (niter == nlist.end()) {
1051                 error << _("XML node describing insert is missing a Redirect node") << endmsg;
1052                 return -1;
1053         }
1054
1055         return 0;
1056 }
1057
1058 nframes_t 
1059 PortInsert::latency() 
1060 {
1061         /* because we deliver and collect within the same cycle,
1062            all I/O is necessarily delayed by at least frames_per_cycle().
1063
1064            if the return port for insert has its own latency, we
1065            need to take that into account too.
1066         */
1067
1068         if (_measured_latency == 0) {
1069                 return _session.engine().frames_per_cycle() + input_latency();
1070         } else {
1071                 return _measured_latency;
1072         }
1073 }
1074
1075 int32_t
1076 PortInsert::can_do (int32_t in, int32_t& out) 
1077 {
1078         if (input_maximum() == -1 && output_maximum() == -1) {
1079
1080                 /* not configured yet */
1081
1082                 out = in;
1083                 return 1;
1084
1085         } else {
1086
1087                 /* the "input" config for a port insert corresponds to how
1088                    many output ports it will have.
1089                 */
1090
1091                 if (output_maximum() == in) {
1092                         out = in;
1093                         return 1;
1094                 } 
1095         }
1096
1097         return -1;
1098 }
1099
1100 int32_t
1101 PortInsert::configure_io (int32_t ignored_magic, int32_t in, int32_t out)
1102 {
1103         /* do not allow configuration to be changed outside the range of
1104            the last request config. or something like that.
1105         */
1106
1107         set_output_maximum (in);
1108         set_output_minimum (in);
1109         set_input_maximum (out);
1110         set_input_minimum (out);
1111
1112         /* this can be momentarily confusing: 
1113
1114            the number of inputs we are required to handle corresponds 
1115            to the number of output ports we need.
1116
1117            the number of outputs we are required to have corresponds
1118            to the number of input ports we need.
1119         */
1120
1121         if (in < 0) {
1122                 in = n_outputs ();
1123         } 
1124
1125         if (out < 0) {
1126                 out = n_inputs ();
1127         }
1128
1129         return ensure_io (out, in, false, this);
1130 }
1131
1132 uint32_t
1133 PortInsert::output_streams() const
1134 {
1135         return n_inputs ();
1136 }
1137
1138 uint32_t
1139 PortInsert::input_streams() const
1140 {
1141         return n_outputs ();
1142 }
1143