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