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