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