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