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