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