imported files retain BWF timestamp info (nick murtagh) ; logarithm plugin controls...
[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         _plugins[0]->set_parameter (port, val);
403         
404         if (automation_list (port).automation_write()) {
405                 automation_list (port).add (_session.audible_frame(), val);
406         }
407
408         _session.set_dirty();
409 }
410
411 void
412 PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
413 {
414         ControlEvent next_event (0, 0.0f);
415         nframes_t now = _session.transport_frame ();
416         nframes_t end = now + nframes;
417         nframes_t offset = 0;
418
419         Glib::Mutex::Lock lm (_automation_lock, Glib::TRY_LOCK);
420
421         if (!lm.locked()) {
422                 connect_and_run (bufs, nbufs, nframes, 0, false, now);
423                 return;
424         }
425
426         if (!find_next_event (now, end, next_event)) {
427                 /* no events have a time within the relevant range */
428                 connect_and_run (bufs, nbufs, nframes, 0, true, now);
429                 return;
430         }
431
432         while (nframes) {
433                 nframes_t cnt = min (((nframes_t) ceil (next_event.when) - now), nframes);
434
435                 connect_and_run (bufs, nbufs, cnt, offset, true, now);
436                 
437                 nframes -= cnt;
438                 now += cnt;
439                 offset += cnt;
440
441                 if (!find_next_event (now, end, next_event)) {
442                         break;
443                 }
444         }
445             
446         /* cleanup anything that is left to do */
447   
448         if (nframes) {
449                 connect_and_run (bufs, nbufs, nframes, offset, true, now);
450         }
451
452 }       
453
454 float
455 PluginInsert::default_parameter_value (uint32_t port)
456 {
457         if (_plugins.empty()) {
458                 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
459                       << endmsg;
460                 /*NOTREACHED*/
461         }
462
463         return _plugins[0]->default_value (port);
464 }
465         
466 void
467 PluginInsert::set_port_automation_state (uint32_t port, AutoState s)
468 {
469         if (port < _plugins[0]->parameter_count()) {
470                 
471                 AutomationList& al = automation_list (port);
472
473                 if (s != al.automation_state()) {
474                         al.set_automation_state (s);
475                         _session.set_dirty ();
476                 }
477         }
478 }
479
480 AutoState
481 PluginInsert::get_port_automation_state (uint32_t port)
482 {
483         if (port < _plugins[0]->parameter_count()) {
484                 return automation_list (port).automation_state();
485         } else {
486                 return Off;
487         }
488 }
489
490 void
491 PluginInsert::protect_automation ()
492 {
493         set<uint32_t> automated_params;
494
495         what_has_automation (automated_params);
496
497         for (set<uint32_t>::iterator i = automated_params.begin(); i != automated_params.end(); ++i) {
498
499                 AutomationList& al = automation_list (*i);
500
501                 switch (al.automation_state()) {
502                 case Write:
503                         al.set_automation_state (Off);
504                         break;
505                 case Touch:
506                         al.set_automation_state (Play);
507                         break;
508                 default:
509                         break;
510                 }
511         }
512 }
513
514 boost::shared_ptr<Plugin>
515 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
516 {
517         boost::shared_ptr<LadspaPlugin> lp;
518 #ifdef HAVE_SLV2
519         boost::shared_ptr<LV2Plugin> lv2p;
520 #endif
521 #ifdef VST_SUPPORT
522         boost::shared_ptr<VSTPlugin> vp;
523 #endif
524 #ifdef HAVE_AUDIOUNITS
525         boost::shared_ptr<AUPlugin> ap;
526 #endif
527
528         if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
529                 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
530 #ifdef HAVE_SLV2
531         } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
532                 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
533 #endif
534 #ifdef VST_SUPPORT
535         } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
536                 return boost::shared_ptr<Plugin> (new VSTPlugin (*vp));
537 #endif
538 #ifdef HAVE_AUDIOUNITS
539         } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
540                 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
541 #endif
542         }
543
544         fatal << string_compose (_("programming error: %1"),
545                           X_("unknown plugin type in PluginInsert::plugin_factory"))
546               << endmsg;
547         /*NOTREACHED*/
548         return boost::shared_ptr<Plugin> ((Plugin*) 0);
549 }
550
551 int32_t
552 PluginInsert::configure_io (int32_t magic, int32_t in, int32_t out)
553 {
554         int32_t ret;
555
556         if ((ret = set_count (magic)) < 0) {
557                 return ret;
558         }
559
560         /* if we're running replicated plugins, each plugin has
561            the same i/o configuration and we may need to announce how many
562            output streams there are.
563
564            if we running a single plugin, we need to configure it.
565         */
566
567         return _plugins[0]->configure_io (in, out);
568 }
569
570 int32_t 
571 PluginInsert::can_do (int32_t in, int32_t& out)
572 {
573         return _plugins[0]->can_do (in, out);
574 }
575
576 XMLNode&
577 PluginInsert::get_state(void)
578 {
579         return state (true);
580 }
581
582 XMLNode&
583 PluginInsert::state (bool full)
584 {
585         char buf[256];
586         XMLNode *node = new XMLNode("Insert");
587
588         node->add_child_nocopy (Redirect::state (full));
589
590         node->add_property ("type", _plugins[0]->state_node_name());
591         node->add_property("unique-id", _plugins[0]->unique_id());
592         node->add_property("count", string_compose("%1", _plugins.size()));
593         node->add_child_nocopy (_plugins[0]->get_state());
594
595         /* add controllables */
596
597         XMLNode* control_node = new XMLNode (X_("controls"));
598
599         for (uint32_t x = 0; x < _plugins[0]->parameter_count(); ++x) {
600                 Controllable* c = _plugins[0]->get_nth_control (x, true);
601                 if (c) {
602                         XMLNode& controllable_state (c->get_state());
603                         controllable_state.add_property ("parameter", to_string (x, std::dec));
604                         control_node->add_child_nocopy (controllable_state);
605                 }
606         }
607         node->add_child_nocopy (*control_node);
608
609         /* add port automation state */
610         XMLNode *autonode = new XMLNode(port_automation_node_name);
611         set<uint32_t> automatable = _plugins[0]->automatable();
612
613         for (set<uint32_t>::iterator x =  automatable.begin(); x != automatable.end(); ++x) {
614
615                 XMLNode* child = new XMLNode("port");
616                 snprintf(buf, sizeof(buf), "%" PRIu32, *x);
617                 child->add_property("number", string(buf));
618
619 #ifdef HAVE_SLV2
620                 LV2Plugin* lv2p = dynamic_cast<LV2Plugin*>(_plugins[0].get());
621                 if (lv2p) {
622                         child->add_property("symbol", string(lv2p->port_symbol(*x)));
623                 }
624 #endif
625
626                 child->add_child_nocopy (automation_list (*x).state (full));
627                 autonode->add_child_nocopy (*child);
628         }
629
630         node->add_child_nocopy (*autonode);
631         
632         return *node;
633 }
634
635 int
636 PluginInsert::set_state(const XMLNode& node)
637 {
638         XMLNodeList nlist = node.children();
639         XMLNodeIterator niter;
640         XMLPropertyList plist;
641         const XMLProperty *prop;
642         ARDOUR::PluginType type;
643
644         if ((prop = node.property ("type")) == 0) {
645                 error << _("XML node describing insert is missing the `type' field") << endmsg;
646                 return -1;
647         }
648
649         if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
650                 type = ARDOUR::LADSPA;
651         } else if (prop->value() == X_("lv2")) {
652                 type = ARDOUR::LV2;
653         } else if (prop->value() == X_("vst")) {
654                 type = ARDOUR::VST;
655         } else if (prop->value() == X_("audiounit")) {
656                 type = ARDOUR::AudioUnit;
657         } else {
658                 error << string_compose (_("unknown plugin type %1 in plugin insert state"),
659                                   prop->value())
660                       << endmsg;
661                 return -1;
662         }
663
664         prop = node.property ("unique-id");
665         if (prop == 0) {
666 #ifdef VST_SUPPORT
667                 /* older sessions contain VST plugins with only an "id" field.
668                  */
669                 
670                 if (type == ARDOUR::VST) {
671                         prop = node.property ("id");
672                 }
673 #endif          
674                 /* recheck  */
675
676                 if (prop == 0) {
677                         error << _("Plugin has no unique ID field") << endmsg;
678                         return -1;
679                 }
680         }
681
682         boost::shared_ptr<Plugin> plugin;
683
684         plugin = find_plugin (_session, prop->value(), type);   
685
686         if (plugin == 0) {
687                 error << string_compose(_("Found a reference to a plugin (\"%1\") that is unknown.\n"
688                                    "Perhaps it was removed or moved since it was last used."), prop->value()) 
689                       << endmsg;
690                 return -1;
691         }
692
693         uint32_t count = 1;
694
695         if ((prop = node.property ("count")) != 0) {
696                 sscanf (prop->value().c_str(), "%u", &count);
697         }
698
699         if (_plugins.size() != count) {
700                 
701                 _plugins.push_back (plugin);
702                 
703                 for (uint32_t n=1; n < count; ++n) {
704                         _plugins.push_back (plugin_factory (plugin));
705                 }
706         }
707
708         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
709                 if ((*niter)->name() == plugin->state_node_name()) {
710                         for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
711                                 (*i)->set_state (**niter);
712                         }
713                         break;
714                 }
715         } 
716
717         if (niter == nlist.end()) {
718                 error << string_compose(_("XML node describing a plugin insert is missing the `%1' information"), plugin->state_node_name()) << endmsg;
719                 return -1;
720         }
721
722         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
723                 if ((*niter)->name() == Redirect::state_node_name) {
724                         Redirect::set_state (**niter);
725                         break;
726                 }
727         }
728
729         if (niter == nlist.end()) {
730                 error << _("XML node describing insert is missing a Redirect node") << endmsg;
731                 return -1;
732         }
733
734         /* look for controllables node */
735         
736         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
737
738                 if ((*niter)->name() != X_("controls")) {
739                         continue;
740                 }
741                 
742                 XMLNodeList grandchildren ((*niter)->children());
743                 XMLProperty* prop;
744                 XMLNodeIterator gciter;
745                 uint32_t param;
746                 
747                 for (gciter = grandchildren.begin(); gciter != grandchildren.end(); ++gciter) {
748                         if ((prop = (*gciter)->property (X_("parameter"))) != 0) {
749                                 param = atoi (prop->value());
750                                 /* force creation of controllable for this parameter */
751                                 _plugins[0]->make_nth_control (param, **gciter);
752                         } 
753                 }
754
755                 break;
756         }
757                 
758         set_automatable ();
759         
760         /* look for port automation node */
761         
762         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
763
764                 if ((*niter)->name() != port_automation_node_name) {
765                         continue;
766                 }
767
768                 XMLNodeList cnodes;
769                 XMLProperty *cprop;
770                 XMLNodeConstIterator iter;
771                 XMLNode *child;
772                 const char *port;
773                 uint32_t port_id;
774                 
775                 cnodes = (*niter)->children ("port");
776                 
777                 for(iter = cnodes.begin(); iter != cnodes.end(); ++iter){
778                         
779                         child = *iter;
780                         
781                         if ((cprop = child->property("number")) != 0) {
782                                 port = cprop->value().c_str();
783                         } else {
784                                 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
785                                 continue;
786                         }
787                         
788                         sscanf (port, "%" PRIu32, &port_id);
789                         
790                         if (port_id >= _plugins[0]->parameter_count()) {
791                                 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
792                                 continue;
793                         }
794
795                         if (!child->children().empty()) {
796                                 automation_list (port_id).set_state (*child->children().front());
797                         } else {
798                                 if ((cprop = child->property("auto")) != 0) {
799                                         
800                                         /* old school */
801
802                                         int x;
803                                         sscanf (cprop->value().c_str(), "0x%x", &x);
804                                         automation_list (port_id).set_automation_state (AutoState (x));
805
806                                 } else {
807                                         
808                                         /* missing */
809                                         
810                                         automation_list (port_id).set_automation_state (Off);
811                                 }
812                         }
813
814                 }
815
816                 /* done */
817
818                 break;
819         } 
820
821         if (niter == nlist.end()) {
822                 warning << string_compose(_("XML node describing a port automation is missing the `%1' information"), port_automation_node_name) << endmsg;
823         }
824         
825         // The name of the PluginInsert comes from the plugin, nothing else
826         set_name(plugin->get_info()->name,this);
827         
828         return 0;
829 }
830
831 string
832 PluginInsert::describe_parameter (uint32_t what)
833 {
834         return _plugins[0]->describe_parameter (what);
835 }
836
837 nframes_t 
838 PluginInsert::latency() 
839 {
840         return _plugins[0]->latency ();
841 }
842         
843 ARDOUR::PluginType
844 PluginInsert::type ()
845 {
846         boost::shared_ptr<LadspaPlugin> lp;
847 #ifdef VST_SUPPORT
848         boost::shared_ptr<VSTPlugin> vp;
849 #endif
850 #ifdef HAVE_AUDIOUNITS
851         boost::shared_ptr<AUPlugin> ap;
852 #endif
853 #ifdef HAVE_LV2
854         boost::shared_ptr<LV2Plugin> lv2p;
855 #endif
856         
857         PluginPtr other = plugin ();
858
859         if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
860                 return ARDOUR::LADSPA;
861 #ifdef VST_SUPPORT
862         } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
863                 return ARDOUR::VST;
864 #endif
865 #ifdef HAVE_AUDIOUNITS
866         } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
867                 return ARDOUR::AudioUnit;
868 #endif
869 #ifdef HAVE_LV2
870         } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
871                 return ARDOUR::LV2;
872 #endif
873         } else {
874                 error << "Unknown plugin type" << endmsg;
875                 /* NOT REACHED */
876                 return (ARDOUR::PluginType) 0;
877         }
878 }
879
880 /***************************************************************
881  Port inserts: send output to a port, pick up input at a port
882  ***************************************************************/
883
884 PortInsert::PortInsert (Session& s, Placement p)
885         : Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
886 {
887         init ();
888         RedirectCreated (this); /* EMIT SIGNAL */
889
890 }
891
892 PortInsert::PortInsert (const PortInsert& other)
893         : Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
894 {
895         init ();
896         RedirectCreated (this); /* EMIT SIGNAL */
897 }
898
899 void
900 PortInsert::init ()
901 {
902 }
903
904 PortInsert::PortInsert (Session& s, const XMLNode& node)
905         : Insert (s, "will change", PreFader)
906 {
907         bitslot = 0xffffffff;
908         if (set_state (node)) {
909                 throw failed_constructor();
910         }
911
912         RedirectCreated (this); /* EMIT SIGNAL */
913 }
914
915 PortInsert::~PortInsert ()
916 {
917         GoingAway ();
918 }
919
920 void
921 PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
922 {
923         if (n_outputs() == 0) {
924                 return;
925         }
926
927         if (!active()) {
928                 /* deliver silence */
929                 silence (nframes);
930                 return;
931         }
932
933         uint32_t n;
934         vector<Port*>::iterator o;
935         vector<Port*>::iterator i;
936
937         /* deliver output */
938
939         for (o = _outputs.begin(), n = 0; o != _outputs.end(); ++o, ++n) {
940                 memcpy (get_output_buffer (n, nframes), bufs[min(nbufs,n)], sizeof (Sample) * nframes);
941                 (*o)->mark_silence (false);
942         }
943         
944         /* collect input */
945         
946         for (i = _inputs.begin(), n = 0; i != _inputs.end(); ++i, ++n) {
947                 memcpy (bufs[min(nbufs,n)], get_input_buffer (n, nframes), sizeof (Sample) * nframes);
948         }
949 }
950
951 XMLNode&
952 PortInsert::get_state(void)
953 {
954         return state (true);
955 }
956
957 XMLNode&
958 PortInsert::state (bool full)
959 {
960         XMLNode *node = new XMLNode("Insert");
961         char buf[32];
962         node->add_child_nocopy (Redirect::state(full)); 
963         node->add_property ("type", "port");
964         snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
965         node->add_property ("bitslot", buf);
966
967         return *node;
968 }
969
970 int
971 PortInsert::set_state(const XMLNode& node)
972 {
973         XMLNodeList nlist = node.children();
974         XMLNodeIterator niter;
975         XMLPropertyList plist;
976         const XMLProperty *prop;
977
978         if ((prop = node.property ("type")) == 0) {
979                 error << _("XML node describing insert is missing the `type' field") << endmsg;
980                 return -1;
981         }
982         
983         if (prop->value() != "port") {
984                 error << _("non-port insert XML used for port plugin insert") << endmsg;
985                 return -1;
986         }
987
988         if ((prop = node.property ("bitslot")) == 0) {
989                 bitslot = _session.next_insert_id();
990         } else {
991                 uint32_t old_bitslot = bitslot;
992                 sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
993
994                 if (old_bitslot != bitslot) {
995                         _session.mark_insert_id (bitslot);
996                 }
997         }
998
999         for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1000                 if ((*niter)->name() == Redirect::state_node_name) {
1001                         Redirect::set_state (**niter);
1002                         break;
1003                 }
1004         }
1005
1006         if (niter == nlist.end()) {
1007                 error << _("XML node describing insert is missing a Redirect node") << endmsg;
1008                 return -1;
1009         }
1010
1011         return 0;
1012 }
1013
1014 nframes_t 
1015 PortInsert::latency() 
1016 {
1017         /* because we deliver and collect within the same cycle,
1018            all I/O is necessarily delayed by at least frames_per_cycle().
1019
1020            if the return port for insert has its own latency, we
1021            need to take that into account too.
1022         */
1023
1024         return _session.engine().frames_per_cycle() + input_latency();
1025 }
1026
1027 int32_t
1028 PortInsert::can_do (int32_t in, int32_t& out) 
1029 {
1030         if (input_maximum() == -1 && output_maximum() == -1) {
1031
1032                 /* not configured yet */
1033
1034                 out = in;
1035                 return 1;
1036
1037         } else {
1038
1039                 /* the "input" config for a port insert corresponds to how
1040                    many output ports it will have.
1041                 */
1042
1043                 if (output_maximum() == in) {
1044                         out = in;
1045                         return 1;
1046                 } 
1047         }
1048
1049         return -1;
1050 }
1051
1052 int32_t
1053 PortInsert::configure_io (int32_t ignored_magic, int32_t in, int32_t out)
1054 {
1055         /* do not allow configuration to be changed outside the range of
1056            the last request config. or something like that.
1057         */
1058
1059         set_output_maximum (in);
1060         set_output_minimum (in);
1061         set_input_maximum (out);
1062         set_input_minimum (out);
1063
1064         /* this can be momentarily confusing: 
1065
1066            the number of inputs we are required to handle corresponds 
1067            to the number of output ports we need.
1068
1069            the number of outputs we are required to have corresponds
1070            to the number of input ports we need.
1071         */
1072
1073         if (in < 0) {
1074                 in = n_outputs ();
1075         } 
1076
1077         if (out < 0) {
1078                 out = n_inputs ();
1079         }
1080
1081         return ensure_io (out, in, false, this);
1082 }
1083
1084 uint32_t
1085 PortInsert::output_streams() const
1086 {
1087         return n_inputs ();
1088 }
1089
1090 uint32_t
1091 PortInsert::input_streams() const
1092 {
1093         return n_outputs ();
1094 }
1095