1 /*
2 * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2007-2014 David Robillard <d@drobilla.net>
5 * Copyright (C) 2008-2009 Sampo Savolainen <v2@iki.fi>
6 * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
7 * Copyright (C) 2016-2017 Tim Mayberry <mojofunk@gmail.com>
8 * Copyright (C) 2018 Johannes Mueller <github@johannes-mueller.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25 #ifdef WAF_BUILD
26 #include "libardour-config.h"
27 #endif
28
29 #include <string>
30
31 #include "pbd/failed_constructor.h"
32 #include "pbd/xml++.h"
33 #include "pbd/types_convert.h"
34
35 #include "ardour/audio_buffer.h"
36 #include "ardour/automation_list.h"
37 #include "ardour/buffer_set.h"
38 #include "ardour/debug.h"
39 #include "ardour/event_type_map.h"
40 #include "ardour/ladspa_plugin.h"
41 #include "ardour/luaproc.h"
42 #include "ardour/lv2_plugin.h"
43 #include "ardour/plugin.h"
44 #include "ardour/plugin_insert.h"
45 #include "ardour/port.h"
46
47 #ifdef WINDOWS_VST_SUPPORT
48 #include "ardour/windows_vst_plugin.h"
49 #endif
50
51 #ifdef LXVST_SUPPORT
52 #include "ardour/lxvst_plugin.h"
53 #endif
54
55 #ifdef MACVST_SUPPORT
56 #include "ardour/mac_vst_plugin.h"
57 #endif
58
59 #ifdef VST3_SUPPORT
60 #include "ardour/vst3_plugin.h"
61 #endif
62
63 #ifdef AUDIOUNIT_SUPPORT
64 #include "ardour/audio_unit.h"
65 #endif
66
67 #include "ardour/session.h"
68 #include "ardour/types.h"
69
70 #include "pbd/i18n.h"
71
72 using namespace std;
73 using namespace ARDOUR;
74 using namespace PBD;
75
76 const string PluginInsert::port_automation_node_name = "PortAutomation";
77
PluginInsert(Session & s,boost::shared_ptr<Plugin> plug)78 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
79 : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
80 , _sc_playback_latency (0)
81 , _sc_capture_latency (0)
82 , _plugin_signal_latency (0)
83 , _signal_analysis_collect_nsamples (0)
84 , _signal_analysis_collect_nsamples_max (0)
85 , _configured (false)
86 , _no_inplace (false)
87 , _strict_io (false)
88 , _custom_cfg (false)
89 , _maps_from_state (false)
90 , _latency_changed (false)
91 , _bypass_port (UINT32_MAX)
92 , _inverted_bypass_enable (false)
93 {
94 g_atomic_int_set (&_stat_reset, 0);
95 g_atomic_int_set (&_flush, 0);
96
97 /* the first is the master */
98 if (plug) {
99 add_plugin (plug);
100 create_automatable_parameters ();
101 const ChanCount& sc (sidechain_input_pins ());
102 if (sc.n_audio () > 0 || sc.n_midi () > 0) {
103 add_sidechain (sc.n_audio (), sc.n_midi ());
104 }
105 }
106 }
107
~PluginInsert()108 PluginInsert::~PluginInsert ()
109 {
110 for (CtrlOutMap::const_iterator i = _control_outputs.begin(); i != _control_outputs.end(); ++i) {
111 boost::dynamic_pointer_cast<ReadOnlyControl>(i->second)->drop_references ();
112 }
113 }
114
115 void
drop_references()116 PluginInsert::drop_references ()
117 {
118 if (!_impulseAnalysisPlugin.expired()) {
119 _impulseAnalysisPlugin.lock()->drop_references ();
120 }
121 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
122 (*i)->drop_references ();
123 }
124
125 /* PluginInsert::_plugins must exist until PBD::Controllable
126 * has emitted drop_references. This is because
127 * AC::get_value() calls _plugin[0]->get_parameter(..)
128 *
129 * Usually ~Automatable, calls drop_references for each
130 * controllable, but that runs after ~PluginInsert.
131 */
132 {
133 Glib::Threads::Mutex::Lock lm (_control_lock);
134 for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) {
135 boost::dynamic_pointer_cast<AutomationControl>(li->second)->drop_references ();
136 }
137 _controls.clear ();
138 }
139 Processor::drop_references ();
140 }
141
142 void
set_strict_io(bool b)143 PluginInsert::set_strict_io (bool b)
144 {
145 if (!_plugins.empty() && _plugins.front()->connect_all_audio_outputs ()) {
146 /* Ignore route setting, allow plugin to add/remove ports */
147 b = false;
148 }
149
150 bool changed = _strict_io != b;
151 _strict_io = b;
152
153 if (changed) {
154 PluginConfigChanged (); /* EMIT SIGNAL */
155 }
156 }
157
158 bool
set_count(uint32_t num)159 PluginInsert::set_count (uint32_t num)
160 {
161 bool require_state = !_plugins.empty();
162
163 if (require_state && num > 1 && plugin (0)->get_info ()->type == ARDOUR::AudioUnit) {
164 // we don't allow to replicate AUs
165 return false;
166 }
167
168 /* this is a bad idea.... we shouldn't do this while active.
169 * only a route holding their redirect_lock should be calling this
170 */
171
172 if (num == 0) {
173 return false;
174 } else if (num > _plugins.size()) {
175 uint32_t diff = num - _plugins.size();
176
177 for (uint32_t n = 0; n < diff; ++n) {
178 boost::shared_ptr<Plugin> p = plugin_factory (_plugins[0]);
179 add_plugin (p);
180
181 if (require_state) {
182 XMLNode& state = _plugins[0]->get_state ();
183 p->set_state (state, Stateful::loading_state_version);
184 }
185
186 if (active ()) {
187 p->activate ();
188 }
189 }
190 PluginConfigChanged (); /* EMIT SIGNAL */
191
192 } else if (num < _plugins.size()) {
193 uint32_t diff = _plugins.size() - num;
194 for (uint32_t n= 0; n < diff; ++n) {
195 _plugins.back()->drop_references ();
196 _plugins.pop_back();
197 }
198 PluginConfigChanged (); /* EMIT SIGNAL */
199 }
200
201 return true;
202 }
203
204
205 void
set_sinks(const ChanCount & c)206 PluginInsert::set_sinks (const ChanCount& c)
207 {
208 _custom_sinks = c;
209 /* no signal, change will only be visible after re-config */
210 }
211
212 void
set_outputs(const ChanCount & c)213 PluginInsert::set_outputs (const ChanCount& c)
214 {
215 bool changed = (_custom_out != c) && _custom_cfg;
216 _custom_out = c;
217 if (changed) {
218 PluginConfigChanged (); /* EMIT SIGNAL */
219 }
220 }
221
222 void
set_custom_cfg(bool b)223 PluginInsert::set_custom_cfg (bool b)
224 {
225 bool changed = _custom_cfg != b;
226 _custom_cfg = b;
227 if (changed) {
228 PluginConfigChanged (); /* EMIT SIGNAL */
229 }
230 }
231
232 bool
set_preset_out(const ChanCount & c)233 PluginInsert::set_preset_out (const ChanCount& c)
234 {
235 bool changed = _preset_out != c;
236 _preset_out = c;
237 if (changed && !_custom_cfg) {
238 PluginConfigChanged (); /* EMIT SIGNAL */
239 }
240 return changed;
241 }
242
243 bool
add_sidechain(uint32_t n_audio,uint32_t n_midi)244 PluginInsert::add_sidechain (uint32_t n_audio, uint32_t n_midi)
245 {
246 // caller must hold process lock
247 if (_sidechain) {
248 return false;
249 }
250 std::ostringstream n;
251 if (n_audio == 0 && n_midi == 0) {
252 n << "TO BE RESET FROM XML";
253 } else if (owner()) {
254 n << "SC " << owner()->name() << "/" << name() << " " << Session::next_name_id ();
255 } else {
256 n << "toBeRenamed" << id().to_s();
257 }
258 SideChain *sc = new SideChain (_session, n.str ());
259 _sidechain = boost::shared_ptr<SideChain> (sc);
260 _sidechain->activate ();
261 for (uint32_t n = 0; n < n_audio; ++n) {
262 _sidechain->input()->add_port ("", owner(), DataType::AUDIO); // add a port, don't connect.
263 }
264 for (uint32_t n = 0; n < n_midi; ++n) {
265 _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect.
266 }
267 PluginConfigChanged (); /* EMIT SIGNAL */
268 return true;
269 }
270
271 bool
del_sidechain()272 PluginInsert::del_sidechain ()
273 {
274 if (!_sidechain) {
275 return false;
276 }
277 _sidechain.reset ();
278 _sc_playback_latency = 0;
279 _sc_capture_latency = 0;
280 PluginConfigChanged (); /* EMIT SIGNAL */
281 return true;
282 }
283
284 void
update_sidechain_name()285 PluginInsert::update_sidechain_name ()
286 {
287 if (!_sidechain) {
288 return;
289 }
290
291 std::ostringstream n;
292
293 n << "SC ";
294 if (owner()) {
295 n << owner()->name() << "/";
296 }
297
298 n << name() << " " << Session::next_name_id ();
299
300 _sidechain->set_name (n.str());
301 }
302
303 void
control_list_automation_state_changed(Evoral::Parameter which,AutoState s)304 PluginInsert::control_list_automation_state_changed (Evoral::Parameter which, AutoState s)
305 {
306 if (which.type() != PluginAutomation)
307 return;
308
309 boost::shared_ptr<AutomationControl> c
310 = boost::dynamic_pointer_cast<AutomationControl>(control (which));
311
312 if (c && s != Off) {
313 _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_sample()), 0);
314 }
315 }
316
317 ChanCount
output_streams() const318 PluginInsert::output_streams() const
319 {
320 assert (_configured);
321 return _configured_out;
322 }
323
324 ChanCount
input_streams() const325 PluginInsert::input_streams() const
326 {
327 assert (_configured);
328 return _configured_in;
329 }
330
331 ChanCount
internal_streams() const332 PluginInsert::internal_streams() const
333 {
334 assert (_configured);
335 return _configured_internal;
336 }
337
338 ChanCount
internal_output_streams() const339 PluginInsert::internal_output_streams() const
340 {
341 assert (!_plugins.empty());
342
343 PluginInfoPtr info = _plugins.front()->get_info();
344
345 if (info->reconfigurable_io()) {
346 ChanCount out = _plugins.front()->output_streams ();
347 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
348 return out;
349 } else {
350 ChanCount out = info->n_outputs;
351 // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
352 out.set_audio (out.n_audio() * _plugins.size());
353 out.set_midi (out.n_midi() * _plugins.size());
354 return out;
355 }
356 }
357
358 ChanCount
internal_input_streams() const359 PluginInsert::internal_input_streams() const
360 {
361 assert (!_plugins.empty());
362
363 ChanCount in;
364
365 PluginInfoPtr info = _plugins.front()->get_info();
366
367 if (info->reconfigurable_io()) {
368 in = _plugins.front()->input_streams();
369 } else {
370 in = info->n_inputs;
371 }
372
373 DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
374
375 if (_match.method == Split) {
376
377 /* we are splitting 1 processor input to multiple plugin inputs,
378 so we have a maximum of 1 stream of each type.
379 */
380 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
381 if (in.get (*t) > 1) {
382 in.set (*t, 1);
383 }
384 }
385 return in;
386
387 } else if (_match.method == Hide) {
388
389 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
390 in.set (*t, in.get (*t) - _match.hide.get (*t));
391 }
392 return in;
393
394 } else {
395
396 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
397 in.set (*t, in.get (*t) * _plugins.size ());
398 }
399
400 return in;
401 }
402 }
403
404 ChanCount
natural_output_streams() const405 PluginInsert::natural_output_streams() const
406 {
407 #ifdef MIXBUS
408 if (is_channelstrip ()) {
409 return ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2));
410 }
411 #endif
412 return _plugins[0]->get_info()->n_outputs;
413 }
414
415 ChanCount
natural_input_streams() const416 PluginInsert::natural_input_streams() const
417 {
418 #ifdef MIXBUS
419 if (is_channelstrip ()) {
420 return ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2));
421 }
422 #endif
423 return _plugins[0]->get_info()->n_inputs;
424 }
425
426 ChanCount
sidechain_input_pins() const427 PluginInsert::sidechain_input_pins() const
428 {
429 return _cached_sidechain_pins;
430 }
431
432 bool
has_no_inputs() const433 PluginInsert::has_no_inputs() const
434 {
435 return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
436 }
437
438 bool
has_no_audio_inputs() const439 PluginInsert::has_no_audio_inputs() const
440 {
441 return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
442 }
443
444 samplecnt_t
plugin_latency() const445 PluginInsert::plugin_latency () const {
446 return _plugins.front()->signal_latency ();
447 }
448
449 bool
is_instrument() const450 PluginInsert::is_instrument() const
451 {
452 PluginInfoPtr pip = _plugins[0]->get_info();
453 return (pip->is_instrument ());
454 }
455
456 bool
has_output_presets(ChanCount in,ChanCount out)457 PluginInsert::has_output_presets (ChanCount in, ChanCount out)
458 {
459 if (!_configured && _plugins[0]->get_info ()->reconfigurable_io ()) {
460 /* collect possible configurations, prefer given in/out */
461 ChanCount aux_in;
462 _plugins[0]->match_variable_io (in, aux_in, out);
463 }
464
465 PluginOutputConfiguration ppc (_plugins[0]->possible_output ());
466
467 if (ppc.size () == 0) {
468 return false;
469 }
470 if (!strict_io () && ppc.size () == 1) {
471 return false;
472 }
473
474 if (strict_io () && ppc.size () == 1) {
475 // "stereo" is currently preferred default for instruments
476 if (ppc.find (2) != ppc.end ()) {
477 return false;
478 }
479 }
480
481 if (ppc.size () == 1 && ppc.find (0) != ppc.end () && !_plugins[0]->get_info ()->reconfigurable_io ()) {
482 // some midi-sequencer (e.g. QMidiArp) or other midi-out plugin
483 // pretending to be an "Instrument"
484 return false;
485 }
486
487 if (!is_instrument ()) {
488 return false;
489 }
490 return true;
491 }
492
493 void
create_automatable_parameters()494 PluginInsert::create_automatable_parameters ()
495 {
496 assert (!_plugins.empty());
497
498 boost::shared_ptr<Plugin> plugin = _plugins.front();
499 set<Evoral::Parameter> a = _plugins.front()->automatable ();
500
501 const uint32_t limit_automatables = Config->get_limit_n_automatables ();
502
503 for (uint32_t i = 0; i < plugin->parameter_count(); ++i) {
504 if (!plugin->parameter_is_control (i)) {
505 continue;
506 }
507
508 ParameterDescriptor desc;
509 plugin->get_parameter_descriptor(i, desc);
510
511 if (!plugin->parameter_is_input (i)) {
512 _control_outputs[i] = boost::shared_ptr<ReadOnlyControl> (new ReadOnlyControl (plugin, desc, i));
513 continue;
514 }
515 Evoral::Parameter param (PluginAutomation, 0, i);
516
517 const bool automatable = a.find(param) != a.end();
518
519 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
520 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
521 if (!automatable || (limit_automatables > 0 && what_can_be_automated ().size() > limit_automatables)) {
522 c->set_flag (Controllable::NotAutomatable);
523 }
524 if (desc.inline_ctrl) {
525 c->set_flag (Controllable::InlineControl);
526 }
527 add_control (c);
528 plugin->set_automation_control (i, c);
529 }
530
531
532 const Plugin::PropertyDescriptors& pdl (plugin->get_supported_properties ());
533 for (Plugin::PropertyDescriptors::const_iterator p = pdl.begin(); p != pdl.end(); ++p) {
534 Evoral::Parameter param (PluginPropertyAutomation, 0, p->first);
535 const ParameterDescriptor& desc = plugin->get_property_descriptor(param.id());
536 if (desc.datatype != Variant::NOTHING) {
537 boost::shared_ptr<AutomationList> list;
538 if (Variant::type_is_numeric(desc.datatype)) {
539 list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
540 }
541 boost::shared_ptr<AutomationControl> c (new PluginPropertyControl(this, param, desc, list));
542 if (!Variant::type_is_numeric(desc.datatype)) {
543 c->set_flag (Controllable::NotAutomatable);
544 }
545 add_control (c);
546 }
547 }
548
549 _bypass_port = plugin->designated_bypass_port ();
550
551 /* special case VST effSetBypass */
552 if (_bypass_port == UINT32_MAX -1) {
553 // emulate VST Bypass
554 Evoral::Parameter param (PluginAutomation, 0, _bypass_port);
555 ParameterDescriptor desc;
556 desc.label = _("Plugin Enable");
557 desc.toggled = true;
558 desc.normal = 1;
559 desc.lower = 0;
560 desc.upper = 1;
561 boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
562 boost::shared_ptr<AutomationControl> c (new PluginControl(this, param, desc, list));
563 add_control (c);
564 }
565
566 if (_bypass_port != UINT32_MAX) {
567 _inverted_bypass_enable = type () == VST3;
568 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
569 if (0 == (ac->flags () & Controllable::NotAutomatable)) {
570 ac->alist()->automation_state_changed.connect_same_thread (*this, boost::bind (&PluginInsert::bypassable_changed, this));
571 ac->Changed.connect_same_thread (*this, boost::bind (&PluginInsert::enable_changed, this));
572 }
573 }
574 plugin->PresetPortSetValue.connect_same_thread (*this, boost::bind (&PluginInsert::preset_load_set_value, this, _1, _2));
575 }
576
577 /** Called when something outside of this host has modified a plugin
578 * parameter. Responsible for propagating the change to two places:
579 *
580 * 1) anything listening to the Control itself
581 * 2) any replicated plugins that make up this PluginInsert.
582 *
583 * The PluginInsert is connected to the ParameterChangedExternally signal for
584 * the first (primary) plugin, and here broadcasts that change to any others.
585 *
586 * XXX We should probably drop this whole replication idea (Paul, October 2015)
587 * since it isn't used by sensible plugin APIs (AU, LV2).
588 */
589 void
parameter_changed_externally(uint32_t which,float val)590 PluginInsert::parameter_changed_externally (uint32_t which, float val)
591 {
592 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
593
594 /* First propagation: alter the underlying value of the control,
595 * without telling the plugin(s) that own/use it to set it.
596 */
597
598 if (!ac) {
599 return;
600 }
601
602 boost::shared_ptr<PluginControl> pc = boost::dynamic_pointer_cast<PluginControl> (ac);
603
604 if (pc) {
605 pc->catch_up_with_external_value (val);
606 }
607
608 /* Second propagation: tell all plugins except the first to
609 update the value of this parameter. For sane plugin APIs,
610 there are no other plugins, so this is a no-op in those
611 cases.
612 */
613
614 Plugins::iterator i = _plugins.begin();
615
616 /* don't set the first plugin, just all the slaves */
617
618 if (i != _plugins.end()) {
619 ++i;
620 for (; i != _plugins.end(); ++i) {
621 (*i)->set_parameter (which, val, 0);
622 }
623 }
624 boost::shared_ptr<Plugin> iasp = _impulseAnalysisPlugin.lock();
625 if (iasp) {
626 iasp->set_parameter (which, val, 0);
627 }
628 }
629
630 int
set_block_size(pframes_t nframes)631 PluginInsert::set_block_size (pframes_t nframes)
632 {
633 int ret = 0;
634 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
635 if ((*i)->set_block_size (nframes) != 0) {
636 ret = -1;
637 }
638 }
639 return ret;
640 }
641
642 void
automation_run(samplepos_t start,pframes_t nframes,bool only_active)643 PluginInsert::automation_run (samplepos_t start, pframes_t nframes, bool only_active)
644 {
645 // XXX does not work when rolling backwards
646 if (_loop_location && nframes > 0) {
647 const samplepos_t loop_start = _loop_location->start ();
648 const samplepos_t loop_end = _loop_location->end ();
649 const samplecnt_t looplen = loop_end - loop_start;
650
651 samplecnt_t remain = nframes;
652 samplepos_t start_pos = start;
653
654 while (remain > 0) {
655 if (start_pos >= loop_end) {
656 sampleoffset_t start_off = (start_pos - loop_start) % looplen;
657 start_pos = loop_start + start_off;
658 }
659 samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos);
660
661 Automatable::automation_run (start_pos, move, only_active);
662 remain -= move;
663 start_pos += move;
664 }
665 return;
666 }
667 Automatable::automation_run (start, nframes, only_active);
668 }
669
670 bool
find_next_event(double now,double end,Evoral::ControlEvent & next_event,bool only_active) const671 PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const
672 {
673 bool rv = Automatable::find_next_event (now, end, next_event, only_active);
674
675 if (_loop_location && now < end) {
676 if (rv) {
677 end = ceil (next_event.when);
678 }
679 const samplepos_t loop_end = _loop_location->end ();
680 assert (now < loop_end); // due to map_loop_range ()
681 if (end > loop_end) {
682 next_event.when = loop_end;
683 rv = true;
684 }
685 }
686 return rv;
687 }
688
689 void
activate()690 PluginInsert::activate ()
691 {
692 _timing_stats.reset ();
693 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
694 (*i)->activate ();
695 }
696
697 Processor::activate ();
698 /* when setting state e.g ProcessorBox::paste_processor_state ()
699 * the plugin is not yet owned by a route.
700 * but no matter. Route::add_processors() will call activate () again
701 */
702 if (!owner ()) {
703 return;
704 }
705
706 const samplecnt_t l = effective_latency ();
707 if (_plugin_signal_latency != l) {
708 _plugin_signal_latency = l;
709 latency_changed ();
710 }
711 }
712
713 void
deactivate()714 PluginInsert::deactivate ()
715 {
716 _timing_stats.reset ();
717 Processor::deactivate ();
718
719 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
720 (*i)->deactivate ();
721 }
722
723 const samplecnt_t l = effective_latency ();
724 if (_plugin_signal_latency != l) {
725 _plugin_signal_latency = l;
726 latency_changed ();
727 }
728 }
729
730 void
flush()731 PluginInsert::flush ()
732 {
733 g_atomic_int_set (&_flush, 1);
734 }
735
736 void
enable(bool yn)737 PluginInsert::enable (bool yn)
738 {
739 if (_bypass_port == UINT32_MAX) {
740 if (yn) {
741 activate ();
742 } else {
743 deactivate ();
744 }
745 } else {
746 if (!_pending_active) {
747 activate ();
748 }
749 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port));
750 const double val = yn ^ _inverted_bypass_enable ? 1.0 : 0.0;
751 ac->set_value (val, Controllable::NoGroup);
752
753 #ifdef ALLOW_VST_BYPASS_TO_FAIL // yet unused, see also vst_plugin.cc
754 /* special case VST.. bypass may fail */
755 if (_bypass_port == UINT32_MAX - 1) {
756 /* check if bypass worked */
757 if (ac->get_value () != val) {
758 warning << _("PluginInsert: VST Bypass failed, falling back to host bypass.") << endmsg;
759 // set plugin to enabled (not-byassed)
760 ac->set_value (1.0, Controllable::NoGroup);
761 // ..and use host-provided hard-bypass
762 if (yn) {
763 activate ();
764 } else {
765 deactivate ();
766 }
767 return;
768 }
769 }
770 #endif
771 ActiveChanged ();
772 }
773 }
774
775 bool
enabled() const776 PluginInsert::enabled () const
777 {
778 if (_bypass_port == UINT32_MAX) {
779 return Processor::enabled ();
780 } else {
781 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
782 return ((ac->get_value () > 0) ^ _inverted_bypass_enable) && _pending_active;
783 }
784 }
785
786 bool
bypassable() const787 PluginInsert::bypassable () const
788 {
789 if (_bypass_port == UINT32_MAX) {
790 return true;
791 } else {
792 boost::shared_ptr<const AutomationControl> ac = boost::const_pointer_cast<AutomationControl> (automation_control (Evoral::Parameter (PluginAutomation, 0, _bypass_port)));
793
794 return !ac->automation_playback ();
795 }
796 }
797
798 void
enable_changed()799 PluginInsert::enable_changed ()
800 {
801 ActiveChanged ();
802 }
803
804 void
bypassable_changed()805 PluginInsert::bypassable_changed ()
806 {
807 BypassableChanged ();
808 }
809
810 bool
write_immediate_event(Evoral::EventType event_type,size_t size,const uint8_t * buf)811 PluginInsert::write_immediate_event (Evoral::EventType event_type, size_t size, const uint8_t* buf)
812 {
813 bool rv = true;
814 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
815 if (!(*i)->write_immediate_event (event_type, size, buf)) {
816 rv = false;
817 }
818 }
819 return rv;
820 }
821
822 void
preset_load_set_value(uint32_t p,float v)823 PluginInsert::preset_load_set_value (uint32_t p, float v)
824 {
825 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, p));
826 if (!ac) {
827 return;
828 }
829
830 if (ac->automation_state() & Play) {
831 return;
832 }
833
834 start_touch (p);
835 ac->set_value (v, Controllable::NoGroup);
836 end_touch (p);
837 }
838
839 void
inplace_silence_unconnected(BufferSet & bufs,const PinMappings & out_map,samplecnt_t nframes,samplecnt_t offset) const840 PluginInsert::inplace_silence_unconnected (BufferSet& bufs, const PinMappings& out_map, samplecnt_t nframes, samplecnt_t offset) const
841 {
842 // TODO optimize: store "unconnected" in a fixed set.
843 // it only changes on reconfiguration.
844 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
845 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
846 bool mapped = false;
847 if (*t == DataType::MIDI && out == 0 && has_midi_bypass ()) {
848 mapped = true; // in-place Midi bypass
849 }
850 for (uint32_t pc = 0; pc < get_count() && !mapped; ++pc) {
851 PinMappings::const_iterator i = out_map.find (pc);
852 if (i == out_map.end ()) {
853 continue;
854 }
855 const ChanMapping& outmap (i->second);
856 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
857 bool valid;
858 uint32_t idx = outmap.get (*t, o, &valid);
859 if (valid && idx == out) {
860 mapped = true;
861 break;
862 }
863 }
864 }
865 if (!mapped) {
866 bufs.get_available (*t, out).silence (nframes, offset);
867 }
868 }
869 }
870 }
871
872 void
connect_and_run(BufferSet & bufs,samplepos_t start,samplepos_t end,double speed,pframes_t nframes,samplecnt_t offset,bool with_auto)873 PluginInsert::connect_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes, samplecnt_t offset, bool with_auto)
874 {
875 // TODO: atomically copy maps & _no_inplace
876 const bool no_inplace = _no_inplace;
877 PinMappings in_map (_in_map); // TODO Split case below overrides, use const& in_map
878 PinMappings const& out_map (_out_map);
879 ChanMapping const& thru_map (_thru_map);
880
881 if (_latency_changed) {
882 /* delaylines are configured with the max possible latency (as reported by the plugin)
883 * so this won't allocate memory (unless the plugin lied about its max latency)
884 * It may still 'click' though, since the fixed delaylines are not de-clicked.
885 * Then again plugin-latency changes are not click-free to begin with.
886 *
887 * This is also worst case, there is currently no concept of per-stream latency.
888 *
889 * e.g. Two identical latent plugins:
890 * 1st plugin: process left (latent), bypass right.
891 * 2nd plugin: bypass left, process right (latent).
892 * -> currently this yields 2 times latency of the plugin,
893 */
894 _latency_changed = false;
895 _delaybuffers.set (ChanCount::max(bufs.count(), _configured_out), plugin_latency ());
896 }
897
898 if (_match.method == Split && !no_inplace) {
899 // TODO: also use this optimization if one source-buffer
900 // feeds _all_ *connected* inputs.
901 // currently this is *first* buffer to all only --
902 // see PluginInsert::check_inplace
903 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
904 if (_configured_internal.get (*t) == 0) {
905 continue;
906 }
907 bool valid;
908 uint32_t first_idx = in_map.p(0).get (*t, 0, &valid);
909 assert (valid && first_idx == 0); // check_inplace ensures this
910 /* copy the first stream's buffer contents to the others */
911 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
912 uint32_t idx = in_map.p(0).get (*t, i, &valid);
913 if (valid) {
914 assert (idx == 0);
915 bufs.get_available (*t, i).read_from (bufs.get_available (*t, first_idx), nframes, offset, offset);
916 }
917 }
918 }
919 /* the copy operation produces a linear monotonic input map */
920 in_map[0] = ChanMapping (natural_input_streams ());
921 }
922
923 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
924 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
925
926 if (with_auto) {
927 boost::shared_ptr<ControlList> cl = _automated_controls.reader ();
928 for (ControlList::const_iterator ci = cl->begin(); ci != cl->end(); ++ci) {
929 AutomationControl& c = *(ci->get());
930 boost::shared_ptr<const Evoral::ControlList> clist (c.list());
931 /* we still need to check for Touch and Latch */
932 if (clist && (static_cast<AutomationList const&> (*clist)).automation_playback ()) {
933 /* 1. Set value at [sub]cycle start */
934 bool valid;
935 float val = clist->rt_safe_eval (start, valid);
936 if (valid) {
937 c.set_value_unchecked(val);
938 }
939 #if 0
940 /* 2. VST3: events between now and end. */
941 assert (_plugins.front()->requires_fixed_sized_buffers());
942 samplepos_t now = start;
943 while (true) {
944 Evoral::ControlEvent next_event (end, 0.0f);
945 find_next_ac_event (*ci, now, end, next_event);
946 if (next_event.when >= end) {
947 break;
948 }
949 now = next_event.when;
950 const float val = c.list()->rt_safe_eval (now, valid);
951 if (valid) {
952 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
953 (*i)->set_parameter (clist->parameter().id(), val, now - start);
954 }
955 }
956 }
957 #endif
958 #if 0
959 /* 3. set value at cycle-end */
960 val = c.list()->rt_safe_eval (end, valid);
961 if (valid) {
962 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
963 (*i)->set_parameter (clist->parameter().id(), val, end - start);
964 }
965 }
966 #endif
967 }
968 }
969 }
970
971 if (_signal_analysis_collect_nsamples_max > 0) {
972 if (_signal_analysis_collect_nsamples < _signal_analysis_collect_nsamples_max) {
973 samplecnt_t ns = std::min ((samplecnt_t) nframes, _signal_analysis_collect_nsamples_max - _signal_analysis_collect_nsamples);
974 _signal_analysis_inputs.set_count (ChanCount (DataType::AUDIO, input_streams().n_audio()));
975
976 for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
977 _signal_analysis_inputs.get_audio(i).read_from (
978 bufs.get_audio(i),
979 ns,
980 _signal_analysis_collect_nsamples);
981 }
982 }
983 _signal_analysis_collect_nsamples += nframes;
984 }
985
986 #ifdef MIXBUS
987 if (is_channelstrip ()) {
988 if (_configured_in.n_audio() > 0) {
989 ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
990 ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
991
992 _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
993
994 for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
995 bufs.get_available (DataType::AUDIO, out).silence (nframes, offset);
996 }
997 }
998 } else
999 #endif
1000 if (no_inplace) {
1001 // TODO optimize -- build maps once.
1002 uint32_t pc = 0;
1003 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1004 ARDOUR::ChanMapping used_outputs;
1005
1006 assert (inplace_bufs.count () >= natural_input_streams () + _configured_out);
1007
1008 /* build used-output map */
1009 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1010 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1011 for (uint32_t out = 0; out < natural_output_streams().get (*t); ++out) {
1012 bool valid;
1013 uint32_t out_idx = out_map.p(pc).get (*t, out, &valid);
1014 if (valid) {
1015 used_outputs.set (*t, out_idx, 1); // mark as used
1016 }
1017 }
1018 }
1019 }
1020 /* copy thru data to outputs before processing in-place */
1021 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1022 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1023 bool valid;
1024 uint32_t in_idx = thru_map.get (*t, out, &valid);
1025 uint32_t m = out + natural_input_streams ().get (*t);
1026 if (valid) {
1027 _delaybuffers.delay (*t, out, inplace_bufs.get_available (*t, m), bufs.get_available (*t, in_idx), nframes, offset, offset);
1028 used_outputs.set (*t, out, 1); // mark as used
1029 } else {
1030 used_outputs.get (*t, out, &valid);
1031 if (valid) {
1032 /* the plugin is expected to write here, but may not :(
1033 * (e.g. drumgizmo w/o kit loaded)
1034 */
1035 inplace_bufs.get_available (*t, m).silence (nframes);
1036 }
1037 }
1038 }
1039 }
1040
1041 pc = 0;
1042 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1043
1044 ARDOUR::ChanMapping i_in_map (natural_input_streams());
1045 ARDOUR::ChanMapping i_out_map (out_map.p(pc));
1046 ARDOUR::ChanCount mapped;
1047
1048 /* map inputs sequentially */
1049 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1050 for (uint32_t in = 0; in < natural_input_streams().get (*t); ++in) {
1051 bool valid;
1052 uint32_t in_idx = in_map.p(pc).get (*t, in, &valid);
1053 uint32_t m = mapped.get (*t);
1054 if (valid) {
1055 inplace_bufs.get_available (*t, m).read_from (bufs.get_available (*t, in_idx), nframes, offset, offset);
1056 } else {
1057 inplace_bufs.get_available (*t, m).silence (nframes, offset);
1058 }
1059 mapped.set (*t, m + 1);
1060 }
1061 }
1062
1063 /* outputs are mapped to inplace_bufs after the inputs */
1064 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1065 i_out_map.offset_to (*t, natural_input_streams ().get (*t));
1066 }
1067
1068 if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
1069 deactivate ();
1070 }
1071 }
1072
1073 /* all instances have completed, now copy data that was written
1074 * and zero unconnected buffers */
1075 ARDOUR::ChanMapping nonzero_out (used_outputs);
1076 if (has_midi_bypass ()) {
1077 nonzero_out.set (DataType::MIDI, 0, 1); // Midi bypass.
1078 }
1079 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1080 for (uint32_t out = 0; out < bufs.count().get (*t); ++out) {
1081 bool valid;
1082 used_outputs.get (*t, out, &valid);
1083 if (!valid) {
1084 nonzero_out.get (*t, out, &valid);
1085 if (!valid) {
1086 bufs.get_available (*t, out).silence (nframes, offset);
1087 }
1088 } else {
1089 uint32_t m = out + natural_input_streams ().get (*t);
1090 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, m), nframes, offset, offset);
1091 }
1092 }
1093 }
1094 } else {
1095 /* in-place processing */
1096 uint32_t pc = 0;
1097 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1098 if ((*i)->connect_and_run(bufs, start, end, speed, in_map.p(pc), out_map.p(pc), nframes, offset)) {
1099 deactivate ();
1100 }
1101 }
1102 // now silence unconnected outputs
1103 inplace_silence_unconnected (bufs, _out_map, nframes, offset);
1104 }
1105
1106 const samplecnt_t l = effective_latency ();
1107 if (_plugin_signal_latency != l) {
1108 _plugin_signal_latency = l;
1109 _signal_analysis_collect_nsamples = 0;
1110 latency_changed ();
1111 }
1112
1113 if (_signal_analysis_collect_nsamples > l) {
1114 assert (_signal_analysis_collect_nsamples_max > 0);
1115 assert (_signal_analysis_collect_nsamples >= nframes);
1116 samplecnt_t sample_pos = _signal_analysis_collect_nsamples - nframes;
1117
1118 samplecnt_t dst_off = sample_pos >= l ? sample_pos - l : 0;
1119 samplecnt_t src_off = sample_pos >= l ? 0 : l - sample_pos;
1120 samplecnt_t n_copy = std::min ((samplecnt_t)nframes, _signal_analysis_collect_nsamples - l);
1121 n_copy = std::min (n_copy, _signal_analysis_collect_nsamples_max - dst_off);
1122
1123 _signal_analysis_outputs.set_count (ChanCount (DataType::AUDIO, output_streams().n_audio()));
1124
1125 for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
1126 _signal_analysis_outputs.get_audio(i).read_from(
1127 bufs.get_audio(i), n_copy, dst_off, src_off);
1128 }
1129
1130 if (dst_off + n_copy == _signal_analysis_collect_nsamples_max) {
1131 _signal_analysis_collect_nsamples_max = 0;
1132 _signal_analysis_collect_nsamples = 0;
1133
1134 AnalysisDataGathered (&_signal_analysis_inputs, &_signal_analysis_outputs); /* EMIT SIGNAL */
1135 }
1136 }
1137 }
1138
1139 void
bypass(BufferSet & bufs,pframes_t nframes)1140 PluginInsert::bypass (BufferSet& bufs, pframes_t nframes)
1141 {
1142 /* bypass the plugin(s) not the whole processor.
1143 * -> use mappings just like connect_and_run
1144 */
1145 // TODO: atomically copy maps & _no_inplace
1146 const bool no_inplace = _no_inplace;
1147 ChanMapping const& in_map (no_sc_input_map ());
1148 ChanMapping const& out_map (output_map ());
1149
1150 bufs.set_count(ChanCount::max(bufs.count(), _configured_internal));
1151 bufs.set_count(ChanCount::max(bufs.count(), _configured_out));
1152
1153 if (no_inplace) {
1154 ChanMapping thru_map (_thru_map);
1155
1156 BufferSet& inplace_bufs = _session.get_noinplace_buffers();
1157 // copy all inputs
1158 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1159 for (uint32_t in = 0; in < _configured_internal.get (*t); ++in) {
1160 inplace_bufs.get_available (*t, in).read_from (bufs.get_available (*t, in), nframes, 0, 0);
1161 }
1162 }
1163 ARDOUR::ChanMapping used_outputs;
1164 // copy thru
1165 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1166 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1167 bool valid;
1168 uint32_t in_idx = thru_map.get (*t, out, &valid);
1169 if (valid) {
1170 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, in_idx), nframes, 0, 0);
1171 used_outputs.set (*t, out, 1); // mark as used
1172 }
1173 }
1174 }
1175 // plugin no-op: assume every plugin has an internal identity map
1176 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1177 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1178 bool valid;
1179 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1180 if (!valid) {
1181 continue;
1182 }
1183 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1184 if (!valid) {
1185 continue;
1186 }
1187 bufs.get_available (*t, out).read_from (inplace_bufs.get_available (*t, in_idx), nframes, 0, 0);
1188 used_outputs.set (*t, out, 1); // mark as used
1189 }
1190 }
1191 // now silence all unused outputs
1192 if (has_midi_bypass ()) {
1193 used_outputs.set (DataType::MIDI, 0, 1); // Midi bypass.
1194 }
1195 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1196 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1197 bool valid;
1198 used_outputs.get (*t, out, &valid);
1199 if (!valid) {
1200 bufs.get_available (*t, out).silence (nframes, 0);
1201 }
1202 }
1203 }
1204 } else {
1205 if (_match.method == Split) {
1206 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1207 if (_configured_internal.get (*t) == 0) {
1208 continue;
1209 }
1210 // copy/feeds _all_ *connected* inputs, copy the first buffer
1211 bool valid;
1212 uint32_t first_idx = in_map.get (*t, 0, &valid);
1213 assert (valid && first_idx == 0); // check_inplace ensures this
1214 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1215 uint32_t idx = in_map.get (*t, i, &valid);
1216 if (valid) {
1217 assert (idx == 0);
1218 bufs.get_available (*t, i).read_from (bufs.get_available (*t, first_idx), nframes, 0, 0);
1219 }
1220 }
1221 }
1222 }
1223
1224 // apply output map and/or monotonic but not identity i/o mappings
1225 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1226 for (uint32_t out = 0; out < _configured_out.get (*t); ++out) {
1227 bool valid;
1228 uint32_t src_idx = out_map.get_src (*t, out, &valid);
1229 if (!valid) {
1230 bufs.get_available (*t, out).silence (nframes, 0);
1231 continue;
1232 }
1233 uint32_t in_idx = in_map.get (*t, src_idx, &valid);
1234 if (!valid) {
1235 bufs.get_available (*t, out).silence (nframes, 0);
1236 continue;
1237 }
1238 if (in_idx != out) {
1239 bufs.get_available (*t, out).read_from (bufs.get_available (*t, in_idx), nframes, 0, 0);
1240 }
1241 }
1242 }
1243 }
1244 }
1245
1246 void
silence(samplecnt_t nframes,samplepos_t start_sample)1247 PluginInsert::silence (samplecnt_t nframes, samplepos_t start_sample)
1248 {
1249 automation_run (start_sample, nframes, true); // evaluate automation only
1250
1251 if (!active ()) {
1252 // XXX delaybuffers need to be offset by nframes
1253 return;
1254 }
1255
1256 _delaybuffers.flush ();
1257
1258 const ChanMapping in_map (natural_input_streams ());
1259 const ChanMapping out_map (natural_output_streams ());
1260 ChanCount maxbuf = ChanCount::max (natural_input_streams (), natural_output_streams());
1261 #ifdef MIXBUS
1262 if (is_channelstrip ()) {
1263 if (_configured_in.n_audio() > 0) {
1264 _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1265 }
1266 } else
1267 #endif
1268 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1269 (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_sample, start_sample + nframes, 1.0, in_map, out_map, nframes, 0);
1270 }
1271 }
1272
1273 void
run(BufferSet & bufs,samplepos_t start_sample,samplepos_t end_sample,double speed,pframes_t nframes,bool)1274 PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, double speed, pframes_t nframes, bool)
1275 {
1276 if (_sidechain) {
1277 // collect sidechain input for complete cycle (!)
1278 // TODO we need delaylines here for latency compensation
1279 _sidechain->run (bufs, start_sample, end_sample, speed, nframes, true);
1280 }
1281
1282 if (g_atomic_int_compare_and_exchange (&_stat_reset, 1, 0)) {
1283 _timing_stats.reset ();
1284 }
1285
1286 if (g_atomic_int_compare_and_exchange (&_flush, 1, 0)) {
1287 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1288 (*i)->flush ();
1289 }
1290 }
1291
1292 if (_pending_active) {
1293 #if defined MIXBUS && defined NDEBUG
1294 if (!is_channelstrip ()) {
1295 _timing_stats.start ();
1296 }
1297 #else
1298 _timing_stats.start ();
1299 #endif
1300 /* run as normal if we are active or moving from inactive to active */
1301
1302 if (_session.transport_rolling() || _session.bounce_processing()) {
1303 automate_and_run (bufs, start_sample, end_sample, speed, nframes);
1304 } else {
1305 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1306 connect_and_run (bufs, start_sample, end_sample, speed, nframes, 0, lm.locked());
1307 }
1308 #if defined MIXBUS && defined NDEBUG
1309 if (!is_channelstrip ()) {
1310 _timing_stats.update ();
1311 }
1312 #else
1313 _timing_stats.update ();
1314 #endif
1315
1316 } else {
1317 _timing_stats.reset ();
1318 // XXX should call ::silence() to run plugin(s) for consistent load.
1319 // We'll need to change this anyway when bypass can be automated
1320 bypass (bufs, nframes);
1321 automation_run (start_sample, nframes, true); // evaluate automation only
1322 _delaybuffers.flush ();
1323 }
1324
1325 _active = _pending_active;
1326
1327 /* we have no idea whether the plugin generated silence or not, so mark
1328 * all buffers appropriately.
1329 */
1330 }
1331
1332 void
automate_and_run(BufferSet & bufs,samplepos_t start,samplepos_t end,double speed,pframes_t nframes)1333 PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t end, double speed, pframes_t nframes)
1334 {
1335 Evoral::ControlEvent next_event (0, 0.0f);
1336 samplecnt_t offset = 0;
1337
1338 Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
1339
1340 if (!lm.locked()) {
1341 connect_and_run (bufs, start, end, speed, nframes, offset, false);
1342 return;
1343 }
1344
1345 /* map start back into loop-range, adjust end */
1346 map_loop_range (start, end);
1347
1348 if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
1349
1350 /* no events have a time within the relevant range */
1351
1352 connect_and_run (bufs, start, end, speed, nframes, offset, true);
1353 return;
1354 }
1355
1356 while (nframes) {
1357
1358 samplecnt_t cnt = min ((samplecnt_t) ceil (fabs (next_event.when - start)), (samplecnt_t) nframes);
1359 assert (cnt > 0);
1360
1361 connect_and_run (bufs, start, start + cnt * speed, speed, cnt, offset, true);
1362
1363 nframes -= cnt;
1364 offset += cnt;
1365 start += cnt * speed;
1366
1367 map_loop_range (start, end);
1368
1369 if (!find_next_event (start, end, next_event)) {
1370 break;
1371 }
1372 }
1373
1374 /* cleanup anything that is left to do */
1375
1376 if (nframes) {
1377 connect_and_run (bufs, start, start + nframes * speed, speed, nframes, offset, true);
1378 }
1379 }
1380
1381 float
default_parameter_value(const Evoral::Parameter & param)1382 PluginInsert::default_parameter_value (const Evoral::Parameter& param)
1383 {
1384 if (param.type() != PluginAutomation)
1385 return 1.0;
1386
1387 if (_plugins.empty()) {
1388 fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
1389 << endmsg;
1390 abort(); /*NOTREACHED*/
1391 }
1392
1393 return _plugins[0]->default_value (param.id());
1394 }
1395
1396
1397 bool
can_reset_all_parameters()1398 PluginInsert::can_reset_all_parameters ()
1399 {
1400 bool all = true;
1401 uint32_t params = 0;
1402 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1403 bool ok=false;
1404 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1405
1406 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1407 continue;
1408 }
1409
1410 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1411 if (!ac) {
1412 continue;
1413 }
1414
1415 ++params;
1416 if (ac->automation_state() & Play) {
1417 all = false;
1418 break;
1419 }
1420 }
1421 return all && (params > 0);
1422 }
1423
1424 bool
reset_parameters_to_default()1425 PluginInsert::reset_parameters_to_default ()
1426 {
1427 bool all = true;
1428
1429 for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
1430 bool ok=false;
1431 const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
1432
1433 if (!ok || !_plugins[0]->parameter_is_input(cid)) {
1434 continue;
1435 }
1436
1437 const float dflt = _plugins[0]->default_value (cid);
1438 const float curr = _plugins[0]->get_parameter (cid);
1439
1440 if (dflt == curr) {
1441 continue;
1442 }
1443
1444 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter(PluginAutomation, 0, cid));
1445 if (!ac) {
1446 continue;
1447 }
1448
1449 if (ac->automation_state() & Play) {
1450 all = false;
1451 continue;
1452 }
1453
1454 ac->set_value (dflt, Controllable::NoGroup);
1455 }
1456 return all;
1457 }
1458
1459 boost::shared_ptr<Plugin>
plugin_factory(boost::shared_ptr<Plugin> other)1460 PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
1461 {
1462 boost::shared_ptr<LadspaPlugin> lp;
1463 boost::shared_ptr<LuaProc> lua;
1464 boost::shared_ptr<LV2Plugin> lv2p;
1465 #ifdef WINDOWS_VST_SUPPORT
1466 boost::shared_ptr<WindowsVSTPlugin> vp;
1467 #endif
1468 #ifdef LXVST_SUPPORT
1469 boost::shared_ptr<LXVSTPlugin> lxvp;
1470 #endif
1471 #ifdef MACVST_SUPPORT
1472 boost::shared_ptr<MacVSTPlugin> mvp;
1473 #endif
1474 #ifdef VST3_SUPPORT
1475 boost::shared_ptr<VST3Plugin> vst3;
1476 #endif
1477 #ifdef AUDIOUNIT_SUPPORT
1478 boost::shared_ptr<AUPlugin> ap;
1479 #endif
1480
1481 if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
1482 return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
1483 } else if ((lua = boost::dynamic_pointer_cast<LuaProc> (other)) != 0) {
1484 return boost::shared_ptr<Plugin> (new LuaProc (*lua));
1485 } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
1486 return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
1487 #ifdef WINDOWS_VST_SUPPORT
1488 } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
1489 return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
1490 #endif
1491 #ifdef LXVST_SUPPORT
1492 } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
1493 return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
1494 #endif
1495 #ifdef MACVST_SUPPORT
1496 } else if ((mvp = boost::dynamic_pointer_cast<MacVSTPlugin> (other)) != 0) {
1497 return boost::shared_ptr<Plugin> (new MacVSTPlugin (*mvp));
1498 #endif
1499 #ifdef VST3_SUPPORT
1500 } else if ((vst3 = boost::dynamic_pointer_cast<VST3Plugin> (other)) != 0) {
1501 return boost::shared_ptr<Plugin> (new VST3Plugin (*vst3));
1502 #endif
1503 #ifdef AUDIOUNIT_SUPPORT
1504 } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
1505 return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
1506 #endif
1507 }
1508
1509 fatal << string_compose (_("programming error: %1"),
1510 X_("unknown plugin type in PluginInsert::plugin_factory"))
1511 << endmsg;
1512 abort(); /*NOTREACHED*/
1513 return boost::shared_ptr<Plugin> ((Plugin*) 0);
1514 }
1515
1516 void
set_input_map(uint32_t num,ChanMapping m)1517 PluginInsert::set_input_map (uint32_t num, ChanMapping m) {
1518 if (num < _in_map.size()) {
1519 bool changed = _in_map[num] != m;
1520 _in_map[num] = m;
1521 changed |= sanitize_maps ();
1522 if (changed) {
1523 mapping_changed ();
1524 }
1525 }
1526 }
1527
1528 void
set_output_map(uint32_t num,ChanMapping m)1529 PluginInsert::set_output_map (uint32_t num, ChanMapping m) {
1530 if (num < _out_map.size()) {
1531 bool changed = _out_map[num] != m;
1532 _out_map[num] = m;
1533 changed |= sanitize_maps ();
1534 if (changed) {
1535 mapping_changed ();
1536 }
1537 }
1538 }
1539
1540 void
set_thru_map(ChanMapping m)1541 PluginInsert::set_thru_map (ChanMapping m) {
1542 bool changed = _thru_map != m;
1543 _thru_map = m;
1544 changed |= sanitize_maps ();
1545 if (changed) {
1546 mapping_changed ();
1547 }
1548 }
1549
1550 bool
pre_seed(const ChanCount & in,const ChanCount & out,const ChanMapping & im,const ChanMapping & om,const ChanMapping & tm)1551 PluginInsert::pre_seed (const ChanCount& in, const ChanCount& out,
1552 const ChanMapping& im, const ChanMapping& om, const ChanMapping& tm)
1553 {
1554 if (_configured) { return false; }
1555 _configured_in = in;
1556 _configured_out = out;
1557 _in_map[0] = im;
1558 _out_map[0] = om;
1559 _thru_map = tm;
1560 _maps_from_state = in.n_total () > 0 && out.n_total () > 0;
1561 return true;
1562 }
1563
1564 ChanMapping
input_map() const1565 PluginInsert::input_map () const
1566 {
1567 ChanMapping rv;
1568 uint32_t pc = 0;
1569 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1570 ChanMapping m (i->second);
1571 const ChanMapping::Mappings& mp ((*i).second.mappings());
1572 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1573 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1574 rv.set (tm->first, i->first + pc * natural_input_streams().get(tm->first), i->second);
1575 }
1576 }
1577 }
1578 return rv;
1579 }
1580
1581
1582 ChanMapping
no_sc_input_map() const1583 PluginInsert::no_sc_input_map () const
1584 {
1585 ChanMapping rv;
1586 uint32_t pc = 0;
1587 for (PinMappings::const_iterator i = _in_map.begin (); i != _in_map.end (); ++i, ++pc) {
1588 ChanMapping m (i->second);
1589 const ChanMapping::Mappings& mp ((*i).second.mappings());
1590 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1591 uint32_t ins = natural_input_streams().get(tm->first) - _cached_sidechain_pins.get(tm->first);
1592 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1593 if (i->first < ins) {
1594 rv.set (tm->first, i->first + pc * ins, i->second);
1595 }
1596 }
1597 }
1598 }
1599 if (has_midi_thru ()) {
1600 rv.set (DataType::MIDI, 0, 0);
1601 }
1602 return rv;
1603 }
1604
1605 ChanMapping
output_map() const1606 PluginInsert::output_map () const
1607 {
1608 ChanMapping rv;
1609 uint32_t pc = 0;
1610 for (PinMappings::const_iterator i = _out_map.begin (); i != _out_map.end (); ++i, ++pc) {
1611 ChanMapping m (i->second);
1612 const ChanMapping::Mappings& mp ((*i).second.mappings());
1613 for (ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
1614 for (ChanMapping::TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
1615 rv.set (tm->first, i->first + pc * natural_output_streams().get(tm->first), i->second);
1616 }
1617 }
1618 }
1619 if (has_midi_bypass ()) {
1620 rv.set (DataType::MIDI, 0, 0);
1621 }
1622
1623 return rv;
1624 }
1625
1626 bool
has_midi_bypass() const1627 PluginInsert::has_midi_bypass () const
1628 {
1629 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1630 && natural_output_streams ().n_midi () == 0) {
1631 return true;
1632 }
1633 return false;
1634 }
1635
1636 bool
has_midi_thru() const1637 PluginInsert::has_midi_thru () const
1638 {
1639 if (_configured_in.n_midi () == 1 && _configured_out.n_midi () == 1
1640 && natural_input_streams ().n_midi () == 0 && natural_output_streams ().n_midi () == 0) {
1641 return true;
1642 }
1643 return false;
1644 }
1645
1646 bool
is_channelstrip() const1647 PluginInsert::is_channelstrip () const
1648 {
1649 return false;
1650 }
1651
1652 void
mapping_changed()1653 PluginInsert::mapping_changed ()
1654 {
1655 PluginMapChanged (); /* EMIT SIGNAL */
1656 _no_inplace = check_inplace ();
1657 _session.set_dirty();
1658 }
1659
1660 bool
check_inplace()1661 PluginInsert::check_inplace ()
1662 {
1663 bool inplace_ok = !_plugins.front()->inplace_broken ();
1664
1665 if (_thru_map.n_total () > 0) {
1666 // TODO once midi-bypass is part of the mapping, ignore it
1667 inplace_ok = false;
1668 }
1669
1670 if (_match.method == Split && inplace_ok) {
1671 assert (get_count() == 1);
1672 assert (_in_map.size () == 1);
1673 if (!_out_map[0].is_monotonic ()) {
1674 inplace_ok = false;
1675 }
1676 if (_configured_internal != _configured_in) {
1677 /* no sidechain -- TODO we could allow this with
1678 * some more logic in PluginInsert::connect_and_run().
1679 *
1680 * PluginInsert::reset_map() already maps it.
1681 */
1682 inplace_ok = false;
1683 }
1684 /* check mapping */
1685 for (DataType::iterator t = DataType::begin(); t != DataType::end() && inplace_ok; ++t) {
1686 if (_configured_internal.get (*t) == 0) {
1687 continue;
1688 }
1689 bool valid;
1690 uint32_t first_idx = _in_map[0].get (*t, 0, &valid);
1691 if (!valid || first_idx != 0) {
1692 // so far only allow to copy the *first* stream's buffer to others
1693 inplace_ok = false;
1694 } else {
1695 for (uint32_t i = 1; i < natural_input_streams ().get (*t); ++i) {
1696 uint32_t idx = _in_map[0].get (*t, i, &valid);
1697 if (valid && idx != first_idx) {
1698 inplace_ok = false;
1699 break;
1700 }
1701 }
1702 }
1703 }
1704
1705 if (inplace_ok) {
1706 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: In Place Split Map\n", name()));
1707 return false;
1708 }
1709 }
1710
1711 for (uint32_t pc = 0; pc < get_count() && inplace_ok ; ++pc) {
1712 if (!_in_map[pc].is_monotonic ()) {
1713 inplace_ok = false;
1714 }
1715 if (!_out_map[pc].is_monotonic ()) {
1716 inplace_ok = false;
1717 }
1718 }
1719
1720 if (inplace_ok) {
1721 /* check if every output is fed by the corresponding input
1722 *
1723 * this prevents in-port 1 -> sink-pin 2 || source-pin 1 -> out port 1, source-pin 2 -> out port 2
1724 * (with in-place, source-pin 1 -> out port 1 overwrites in-port 1)
1725 *
1726 * but allows in-port 1 -> sink-pin 2 || source-pin 2 -> out port 1
1727 */
1728 ChanMapping const& in_map (input_map ());
1729 const ChanMapping::Mappings out_m (output_map ().mappings ());
1730 for (ChanMapping::Mappings::const_iterator t = out_m.begin (); t != out_m.end () && inplace_ok; ++t) {
1731 for (ChanMapping::TypeMapping::const_iterator c = (*t).second.begin (); c != (*t).second.end () ; ++c) {
1732 /* src-pin: c->first, out-port: c->second */
1733 bool valid;
1734 uint32_t in_port = in_map.get (t->first, c->first, &valid);
1735 if (valid && in_port != c->second) {
1736 inplace_ok = false;
1737 break;
1738 }
1739 }
1740 }
1741 }
1742
1743 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: %2\n", name(), inplace_ok ? "In-Place" : "No Inplace Processing"));
1744 return !inplace_ok; // no-inplace
1745 }
1746
1747 bool
sanitize_maps()1748 PluginInsert::sanitize_maps ()
1749 {
1750 bool changed = false;
1751 /* strip dead wood */
1752 PinMappings new_ins;
1753 PinMappings new_outs;
1754 ChanMapping new_thru;
1755
1756 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1757 ChanMapping new_in;
1758 ChanMapping new_out;
1759 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1760 for (uint32_t i = 0; i < natural_input_streams().get (*t); ++i) {
1761 bool valid;
1762 uint32_t idx = _in_map[pc].get (*t, i, &valid);
1763 if (valid && idx < _configured_internal.get (*t)) {
1764 new_in.set (*t, i, idx);
1765 }
1766 }
1767 for (uint32_t o = 0; o < natural_output_streams().get (*t); ++o) {
1768 bool valid;
1769 uint32_t idx = _out_map[pc].get (*t, o, &valid);
1770 if (valid && idx < _configured_out.get (*t)) {
1771 new_out.set (*t, o, idx);
1772 }
1773 }
1774 }
1775 if (_in_map[pc] != new_in || _out_map[pc] != new_out) {
1776 changed = true;
1777 }
1778 new_ins[pc] = new_in;
1779 new_outs[pc] = new_out;
1780 }
1781
1782 /* prevent dup output assignments */
1783 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1784 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1785 bool mapped = false;
1786 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1787 bool valid;
1788 uint32_t idx = new_outs[pc].get_src (*t, o, &valid);
1789 if (valid && mapped) {
1790 new_outs[pc].unset (*t, idx);
1791 } else if (valid) {
1792 mapped = true;
1793 }
1794 }
1795 }
1796 }
1797
1798 /* remove excess thru */
1799 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1800 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1801 bool valid;
1802 uint32_t idx = _thru_map.get (*t, o, &valid);
1803 if (valid && idx < _configured_internal.get (*t)) {
1804 new_thru.set (*t, o, idx);
1805 }
1806 }
1807 }
1808
1809 /* prevent out + thru, existing plugin outputs override thru */
1810 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1811 for (uint32_t o = 0; o < _configured_out.get (*t); ++o) {
1812 bool mapped = false;
1813 bool valid;
1814 for (uint32_t pc = 0; pc < get_count(); ++pc) {
1815 new_outs[pc].get_src (*t, o, &mapped);
1816 if (mapped) { break; }
1817 }
1818 if (!mapped) { continue; }
1819 uint32_t idx = new_thru.get (*t, o, &valid);
1820 if (mapped) {
1821 new_thru.unset (*t, idx);
1822 }
1823 }
1824 }
1825
1826 if (has_midi_bypass ()) {
1827 // TODO: include midi-bypass in the thru set,
1828 // remove dedicated handling.
1829 new_thru.unset (DataType::MIDI, 0);
1830 }
1831
1832 if (_in_map != new_ins || _out_map != new_outs || _thru_map != new_thru) {
1833 changed = true;
1834 }
1835 _in_map = new_ins;
1836 _out_map = new_outs;
1837 _thru_map = new_thru;
1838
1839 return changed;
1840 }
1841
1842 bool
reset_map(bool emit)1843 PluginInsert::reset_map (bool emit)
1844 {
1845 const PinMappings old_in (_in_map);
1846 const PinMappings old_out (_out_map);
1847
1848 _in_map.clear ();
1849 _out_map.clear ();
1850 _thru_map = ChanMapping ();
1851
1852 /* build input map */
1853 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1854 uint32_t sc = 0; // side-chain round-robin (all instances)
1855 uint32_t pc = 0;
1856 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1857 const uint32_t nis = natural_input_streams ().get(*t);
1858 const uint32_t stride = nis - sidechain_input_pins().get (*t);
1859
1860 /* SC inputs are last in the plugin-insert.. */
1861 const uint32_t sc_start = _configured_in.get (*t);
1862 const uint32_t sc_len = _configured_internal.get (*t) - sc_start;
1863 /* ...but may not be at the end of the plugin ports.
1864 * in case the side-chain is not the last port, shift connections back.
1865 * and connect to side-chain
1866 */
1867 uint32_t shift = 0;
1868 uint32_t ic = 0; // split inputs
1869 const uint32_t cend = _configured_in.get (*t);
1870
1871 for (uint32_t in = 0; in < nis; ++in) {
1872 const Plugin::IOPortDescription& iod (_plugins[pc]->describe_io_port (*t, true, in));
1873 if (iod.is_sidechain) {
1874 /* connect sidechain sinks to sidechain inputs in round-robin fashion */
1875 if (sc_len > 0) {// side-chain may be hidden
1876 _in_map[pc].set (*t, in, sc_start + sc);
1877 sc = (sc + 1) % sc_len;
1878 }
1879 ++shift;
1880 } else {
1881 if (_match.method == Split) {
1882 if (cend == 0) { continue; }
1883 if (_strict_io && ic + stride * pc >= cend) {
1884 break;
1885 }
1886 /* connect *no* sidechain sinks in round-robin fashion */
1887 _in_map[pc].set (*t, in, ic + stride * pc);
1888 if (_strict_io && (ic + 1) == cend) {
1889 break;
1890 }
1891 ic = (ic + 1) % cend;
1892 } else {
1893 uint32_t s = in - shift;
1894 if (stride * pc + s < cend) {
1895 _in_map[pc].set (*t, in, s + stride * pc);
1896 }
1897 }
1898 }
1899 }
1900 }
1901 }
1902
1903 /* build output map */
1904 uint32_t pc = 0;
1905 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
1906 _out_map[pc] = ChanMapping (ChanCount::min (natural_output_streams(), _configured_out));
1907 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
1908 _out_map[pc].offset_to(*t, pc * natural_output_streams().get(*t));
1909 }
1910 }
1911
1912 sanitize_maps ();
1913 if (old_in == _in_map && old_out == _out_map) {
1914 return false;
1915 }
1916 if (emit) {
1917 mapping_changed ();
1918 }
1919 return true;
1920 }
1921
1922 bool
configure_io(ChanCount in,ChanCount out)1923 PluginInsert::configure_io (ChanCount in, ChanCount out)
1924 {
1925 Match old_match = _match;
1926 ChanCount old_in;
1927 ChanCount old_internal;
1928 ChanCount old_out;
1929 ChanCount old_pins;
1930
1931 old_pins = natural_input_streams();
1932 old_in = _configured_in;
1933 old_out = _configured_out;
1934 old_internal = _configured_internal;
1935
1936 _configured_in = in;
1937 _configured_internal = in;
1938 _configured_out = out;
1939
1940 ChanCount aux_in;
1941
1942 if (_sidechain) {
1943 /* TODO hide midi-bypass, and custom outs. Best /fake/ "out" here.
1944 * (currently _sidechain->configure_io always succeeds
1945 * since Processor::configure_io() succeeds)
1946 */
1947 if (!_sidechain->configure_io (in, out)) {
1948 DEBUG_TRACE (DEBUG::ChanMapping, "Sidechain configuration failed\n");
1949 return false;
1950 }
1951 _configured_internal += _sidechain->input()->n_ports();
1952 aux_in = _sidechain->input()->n_ports();
1953
1954 // include (static_cast<Route*>owner())->name() ??
1955 _sidechain->input ()-> set_pretty_name (string_compose (_("SC %1"), name ()));
1956 }
1957
1958 /* get plugin configuration */
1959 _match = private_can_support_io_configuration (in, out); // sets out
1960 #ifndef NDEBUG
1961 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
1962 DEBUG_STR_DECL(a);
1963 DEBUG_STR_APPEND(a, string_compose ("%1: ", name()));
1964 DEBUG_STR_APPEND(a, _match);
1965 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
1966 }
1967 #endif
1968
1969 /* set the matching method and number of plugins that we will use to meet this configuration */
1970 if (set_count (_match.plugins) == false) {
1971 PluginIoReConfigure (); /* EMIT SIGNAL */
1972 _configured = false;
1973 return false;
1974 }
1975
1976 /* configure plugins */
1977 switch (_match.method) {
1978 case Split:
1979 case Hide:
1980 if (_plugins.front()->reconfigure_io (natural_input_streams(), ChanCount (), out) == false) {
1981 PluginIoReConfigure (); /* EMIT SIGNAL */
1982 _configured = false;
1983 return false;
1984 }
1985 break;
1986 case Delegate:
1987 {
1988 ChanCount din (in);
1989 ChanCount daux (aux_in);
1990 ChanCount dout (_configured_out);
1991 if (_custom_cfg) {
1992 if (_custom_sinks.n_total () > 0) {
1993 din = std::min (natural_input_streams(), _custom_sinks);
1994 if (_custom_sinks > natural_input_streams()) {
1995 daux = _custom_sinks - din;
1996 }
1997 }
1998 dout = _custom_out;
1999 } else if (_preset_out.n_audio () > 0) {
2000 dout.set (DataType::AUDIO, _preset_out.n_audio ());
2001 } else if (dout.n_midi () > 0 && dout.n_audio () == 0) {
2002 dout.set (DataType::AUDIO, 2);
2003 }
2004 //if (dout.n_audio () == 0) { dout.set (DataType::AUDIO, 1); } // XXX why?
2005 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate lookup: %2 %3 %4\n", name(), din, daux, dout));
2006 bool const r = _plugins.front()->match_variable_io (din, daux, dout);
2007 assert (r);
2008 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: Delegate configuration: %2 %3 %4\n", name(), din, daux, dout));
2009 if (_plugins.front()->reconfigure_io (din, daux, dout) == false) {
2010 PluginIoReConfigure (); /* EMIT SIGNAL */
2011 _configured = false;
2012 return false;
2013 }
2014 if (!_custom_cfg) {
2015 _custom_sinks = din;
2016 }
2017 }
2018 break;
2019 default:
2020 if (_plugins.front()->reconfigure_io (in, aux_in, out) == false) {
2021 PluginIoReConfigure (); /* EMIT SIGNAL */
2022 _configured = false;
2023 return false;
2024 }
2025 break;
2026 }
2027
2028 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: cfg:%2 state:%3 chn-in:%4 chn-out:%5 inpin:%6 match:%7 cust:%8 size-in:%9 size-out:%10\n",
2029 name (),
2030 _configured ? "Y" : "N",
2031 _maps_from_state ? "Y" : "N",
2032 old_in == in ? "==" : "!=",
2033 old_out == out ? "==" : "!=",
2034 old_pins == natural_input_streams () ? "==" : "!=",
2035 old_match.method == _match.method ? "==" : "!=",
2036 old_match.custom_cfg == _match.custom_cfg ? "==" : "!=",
2037 _in_map.size() == get_count () ? "==" : "!=",
2038 _out_map.size() == get_count () ? "==" : "!="
2039 ));
2040
2041 bool mapping_changed = false;
2042 if (old_in == in && old_out == out
2043 && _configured
2044 && old_pins == natural_input_streams ()
2045 && old_match.method == _match.method
2046 && old_match.custom_cfg == _match.custom_cfg
2047 && _in_map.size() == _out_map.size()
2048 && _in_map.size() == get_count ()
2049 ) {
2050 /* If the configuration has not changed, keep the mapping */
2051 mapping_changed = sanitize_maps ();
2052 } else if (_match.custom_cfg && _configured) {
2053 /* don't touch the map in manual mode */
2054 mapping_changed = sanitize_maps ();
2055 } else {
2056 #ifdef MIXBUS
2057 if (is_channelstrip ()) {
2058 /* fake channel map - for wire display */
2059 _in_map.clear ();
2060 _out_map.clear ();
2061 _thru_map = ChanMapping ();
2062 _in_map[0] = ChanMapping (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
2063 _out_map[0] = ChanMapping (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
2064 /* set "thru" map for in-place forward of audio */
2065 for (uint32_t i = 2; i < _configured_in.n_audio(); ++i) {
2066 _thru_map.set (DataType::AUDIO, i, i);
2067 }
2068 /* and midi (after implicit 1st channel bypass) */
2069 for (uint32_t i = 1; i < _configured_in.n_midi(); ++i) {
2070 _thru_map.set (DataType::MIDI, i, i);
2071 }
2072 } else
2073 #endif
2074 if (_maps_from_state && old_in == in && old_out == out) {
2075 mapping_changed = true;
2076 sanitize_maps ();
2077 } else {
2078 /* generate a new mapping */
2079 mapping_changed = reset_map (false);
2080 }
2081 _maps_from_state = false;
2082 }
2083
2084 if (mapping_changed) {
2085 PluginMapChanged (); /* EMIT SIGNAL */
2086
2087 #ifndef NDEBUG
2088 if (DEBUG_ENABLED(DEBUG::ChanMapping)) {
2089 uint32_t pc = 0;
2090 DEBUG_STR_DECL(a);
2091 DEBUG_STR_APPEND(a, "\n--------<<--------\n");
2092 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
2093 if (pc > 0) {
2094 DEBUG_STR_APPEND(a, "----><----\n");
2095 }
2096 DEBUG_STR_APPEND(a, string_compose ("Channel Map for %1 plugin %2\n", name(), pc));
2097 DEBUG_STR_APPEND(a, " * Inputs:\n");
2098 DEBUG_STR_APPEND(a, _in_map[pc]);
2099 DEBUG_STR_APPEND(a, " * Outputs:\n");
2100 DEBUG_STR_APPEND(a, _out_map[pc]);
2101 }
2102 DEBUG_STR_APPEND(a, " * Thru:\n");
2103 DEBUG_STR_APPEND(a, _thru_map);
2104 DEBUG_STR_APPEND(a, "-------->>--------\n");
2105 DEBUG_TRACE (DEBUG::ChanMapping, DEBUG_STR(a).str());
2106 }
2107 #endif
2108 }
2109
2110 _no_inplace = check_inplace ();
2111
2112 /* only the "noinplace_buffers" thread buffers need to be this large,
2113 * this can be optimized. other buffers are fine with
2114 * ChanCount::max (natural_input_streams (), natural_output_streams())
2115 * and route.cc's max (configured_in, configured_out)
2116 *
2117 * no-inplace copies "thru" outputs (to emulate in-place) for
2118 * all outputs (to prevent overwrite) into a temporary space
2119 * which also holds input buffers (in case the plugin does process
2120 * in-place and overwrites those).
2121 *
2122 * this buffers need to be at least as
2123 * natural_input_streams () + possible outputs.
2124 *
2125 * sidechain inputs add a constraint on the input:
2126 * configured input + sidechain (=_configured_internal)
2127 *
2128 * NB. this also satisfies
2129 * max (natural_input_streams(), natural_output_streams())
2130 * which is needed for silence runs
2131 */
2132 _required_buffers = ChanCount::max (_configured_internal,
2133 natural_input_streams () + ChanCount::max (_configured_out, natural_output_streams () * get_count ()));
2134
2135 if (old_in != in || old_out != out || old_internal != _configured_internal
2136 || old_pins != natural_input_streams ()
2137 || (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
2138 ) {
2139 PluginIoReConfigure (); /* EMIT SIGNAL */
2140 }
2141
2142 _delaybuffers.configure (_configured_out, _plugins.front ()->max_latency ());
2143 _latency_changed = true;
2144
2145 /* we don't know the analysis window size, so we must work with the
2146 * current buffer size here. each request for data fills in these
2147 * buffers and the analyser makes sure it gets enough data for the
2148 * analysis window. We also only analyze audio, so we can ignore
2149 * MIDI buffers.
2150 */
2151 ChanCount cc_analysis_in (DataType::AUDIO, in.n_audio());
2152 ChanCount cc_analysis_out (DataType::AUDIO, out.n_audio());
2153
2154 session().ensure_buffer_set (_signal_analysis_inputs, cc_analysis_in);
2155 _signal_analysis_inputs.set_count (cc_analysis_in);
2156
2157 session().ensure_buffer_set (_signal_analysis_outputs, cc_analysis_out);
2158 _signal_analysis_outputs.set_count (cc_analysis_out);
2159
2160 // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
2161
2162 _configured = true;
2163 return Processor::configure_io (in, out);
2164 }
2165
2166 /** Decide whether this PluginInsert can support a given IO configuration.
2167 * To do this, we run through a set of possible solutions in rough order of
2168 * preference.
2169 *
2170 * @param in Required input channel count.
2171 * @param out Filled in with the output channel count if we return true.
2172 * @return true if the given IO configuration can be supported.
2173 */
2174 bool
can_support_io_configuration(const ChanCount & in,ChanCount & out)2175 PluginInsert::can_support_io_configuration (const ChanCount& in, ChanCount& out)
2176 {
2177 if (_sidechain) {
2178 _sidechain->can_support_io_configuration (in, out); // never fails, sets "out"
2179 }
2180 return private_can_support_io_configuration (in, out).method != Impossible;
2181 }
2182
2183 PluginInsert::Match
private_can_support_io_configuration(ChanCount const & in,ChanCount & out) const2184 PluginInsert::private_can_support_io_configuration (ChanCount const& in, ChanCount& out) const
2185 {
2186 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2187 // preseed hint (for variable i/o)
2188 out.set (DataType::AUDIO, _preset_out.n_audio ());
2189 }
2190
2191 Match rv = internal_can_support_io_configuration (in, out);
2192
2193 if (!_custom_cfg && _preset_out.n_audio () > 0) {
2194 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: using output preset: %2\n", name(), _preset_out));
2195 out.set (DataType::AUDIO, _preset_out.n_audio ());
2196 }
2197 return rv;
2198 }
2199
2200 /** A private version of can_support_io_configuration which returns the method
2201 * by which the configuration can be matched, rather than just whether or not
2202 * it can be.
2203 */
2204 PluginInsert::Match
internal_can_support_io_configuration(ChanCount const & inx,ChanCount & out) const2205 PluginInsert::internal_can_support_io_configuration (ChanCount const & inx, ChanCount& out) const
2206 {
2207 if (_plugins.empty()) {
2208 return Match();
2209 }
2210
2211 #ifdef MIXBUS
2212 if (is_channelstrip ()) {
2213 out = inx;
2214 return Match (ExactMatch, 1);
2215 }
2216 #endif
2217
2218 /* if a user specified a custom cfg, so be it. */
2219 if (_custom_cfg) {
2220 PluginInfoPtr info = _plugins.front()->get_info();
2221 out = _custom_out;
2222 if (info->reconfigurable_io()) {
2223 return Match (Delegate, 1, _strict_io, true);
2224 } else {
2225 return Match (ExactMatch, get_count(), _strict_io, true);
2226 }
2227 }
2228
2229 /* try automatic configuration */
2230 Match m = PluginInsert::automatic_can_support_io_configuration (inx, out);
2231
2232 PluginInfoPtr info = _plugins.front()->get_info();
2233 ChanCount inputs = info->n_inputs;
2234 ChanCount outputs = info->n_outputs;
2235
2236 /* handle case strict-i/o */
2237 if (_strict_io && m.method != Impossible) {
2238 m.strict_io = true;
2239
2240 /* special case MIDI instruments */
2241 if (is_instrument ()) {
2242 // output = midi-bypass + at most master-out channels.
2243 ChanCount max_out (DataType::AUDIO, 2); // TODO use master-out
2244 max_out.set (DataType::MIDI, out.get(DataType::MIDI));
2245 out = ChanCount::min (out, max_out);
2246 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o instrument\n", name()));
2247 return m;
2248 }
2249
2250 switch (m.method) {
2251 case NoInputs:
2252 if (inx.n_audio () != out.n_audio ()) { // ignore midi bypass
2253 /* replicate processor to match output count (generators and such)
2254 * at least enough to feed every output port. */
2255 uint32_t f = 1; // at least one. e.g. control data filters, no in, no out.
2256 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2257 uint32_t nout = outputs.get (*t);
2258 if (nout == 0 || inx.get(*t) == 0) { continue; }
2259 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nout));
2260 }
2261 out = inx;
2262 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: special case strict-i/o for generator\n", name()));
2263 return Match (Replicate, f, _strict_io);
2264 }
2265 break;
2266 default:
2267 break;
2268 }
2269
2270 out = inx;
2271 return m;
2272 }
2273
2274 if (m.method != Impossible) {
2275 return m;
2276 }
2277
2278 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2279
2280 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: resolving 'Impossible' match...\n", name()));
2281
2282 if (info->reconfigurable_io()) {
2283 //out = inx; // hint
2284 ChanCount main_in = inx;
2285 ChanCount aux_in = sidechain_input_pins ();
2286 if (out.n_midi () > 0 && out.n_audio () == 0) {
2287 out.set (DataType::AUDIO, 2);
2288 }
2289 //if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); } // why?
2290 bool const r = _plugins.front()->match_variable_io (main_in, aux_in, out);
2291 if (!r) {
2292 // houston, we have a problem.
2293 return Match (Impossible, 0);
2294 }
2295 // midi bypass
2296 if (inx.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2297 return Match (Delegate, 1, _strict_io);
2298 }
2299
2300 ChanCount midi_bypass;
2301 if (inx.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2302 midi_bypass.set (DataType::MIDI, 1);
2303 }
2304
2305 // add at least as many plugins so that output count matches input count (w/o sidechain pins)
2306 uint32_t f = 0;
2307 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2308 uint32_t nin = ns_inputs.get (*t);
2309 uint32_t nout = outputs.get (*t);
2310 if (nin == 0 || inx.get(*t) == 0) { continue; }
2311 // prefer floor() so the count won't overly increase IFF (nin < nout)
2312 f = max (f, (uint32_t) floor (inx.get(*t) / (float)nout));
2313 }
2314 if (f > 0 && outputs * f >= _configured_out) {
2315 out = outputs * f + midi_bypass;
2316 return Match (Replicate, f, _strict_io);
2317 }
2318
2319 // add at least as many plugins needed to connect all inputs (w/o sidechain pins)
2320 f = 0;
2321 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2322 uint32_t nin = ns_inputs.get (*t);
2323 if (nin == 0 || inx.get(*t) == 0) { continue; }
2324 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2325 }
2326 if (f > 0) {
2327 out = outputs * f + midi_bypass;
2328 return Match (Replicate, f, _strict_io);
2329 }
2330
2331 // add at least as many plugins needed to connect all inputs
2332 f = 1;
2333 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2334 uint32_t nin = inputs.get (*t);
2335 if (nin == 0 || inx.get(*t) == 0) { continue; }
2336 f = max (f, (uint32_t) ceil (inx.get(*t) / (float)nin));
2337 }
2338 out = outputs * f + midi_bypass;
2339 return Match (Replicate, f, _strict_io);
2340 }
2341
2342 /* this is the original Ardour 3/4 behavior, mainly for backwards compatibility */
2343 PluginInsert::Match
automatic_can_support_io_configuration(ChanCount const & inx,ChanCount & out) const2344 PluginInsert::automatic_can_support_io_configuration (ChanCount const& inx, ChanCount& out) const
2345 {
2346 if (_plugins.empty()) {
2347 return Match();
2348 }
2349
2350 PluginInfoPtr info = _plugins.front()->get_info();
2351 ChanCount in; in += inx;
2352 ChanCount midi_bypass;
2353
2354 if (info->reconfigurable_io()) {
2355 /* Plugin has flexible I/O, so delegate to it
2356 * pre-seed outputs, plugin tries closest match
2357 */
2358 //out = in; // hint
2359 ChanCount aux_in = sidechain_input_pins ();
2360 if (out.n_midi () > 0 && out.n_audio () == 0) { out.set (DataType::AUDIO, 2); }
2361 if (out.n_audio () == 0) { out.set (DataType::AUDIO, 1); }
2362 bool const r = _plugins.front()->match_variable_io (in, aux_in, out);
2363 if (!r) {
2364 return Match (Impossible, 0);
2365 }
2366 // midi bypass
2367 if (in.n_midi () > 0 && out.n_midi () == 0) { out.set (DataType::MIDI, 1); }
2368 return Match (Delegate, 1);
2369 }
2370
2371 ChanCount inputs = info->n_inputs;
2372 ChanCount outputs = info->n_outputs;
2373 ChanCount ns_inputs = inputs - sidechain_input_pins ();
2374
2375 if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
2376 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: bypassing midi-data\n", name()));
2377 midi_bypass.set (DataType::MIDI, 1);
2378 }
2379 if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
2380 DEBUG_TRACE (DEBUG::ChanMapping, string_compose ("%1: hiding midi-port from plugin\n", name()));
2381 in.set(DataType::MIDI, 0);
2382 }
2383
2384 // add internally provided sidechain ports
2385 ChanCount insc = in + sidechain_input_ports ();
2386
2387 bool no_inputs = true;
2388 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2389 if (inputs.get (*t) != 0) {
2390 no_inputs = false;
2391 break;
2392 }
2393 }
2394
2395 if (no_inputs) {
2396 /* no inputs so we can take any input configuration since we throw it away */
2397 out = outputs + midi_bypass;
2398 return Match (NoInputs, 1);
2399 }
2400
2401 /* Plugin inputs match requested inputs + side-chain-ports exactly */
2402 if (inputs == insc) {
2403 out = outputs + midi_bypass;
2404 return Match (ExactMatch, 1);
2405 }
2406
2407 /* Plugin inputs matches without side-chain-pins */
2408 if (ns_inputs == in) {
2409 out = outputs + midi_bypass;
2410 return Match (ExactMatch, 1);
2411 }
2412
2413 /* We may be able to run more than one copy of the plugin within this insert
2414 to cope with the insert having more inputs than the plugin.
2415 We allow replication only for plugins with either zero or 1 inputs and outputs
2416 for every valid data type.
2417 */
2418
2419 uint32_t f = 0;
2420 bool can_replicate = true;
2421 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2422
2423 // ignore side-chains
2424 uint32_t nin = ns_inputs.get (*t);
2425
2426 // No inputs of this type
2427 if (nin == 0 && in.get(*t) == 0) {
2428 continue;
2429 }
2430
2431 if (nin != 1 || outputs.get (*t) != 1) {
2432 can_replicate = false;
2433 break;
2434 }
2435
2436 // Potential factor not set yet
2437 if (f == 0) {
2438 f = in.get(*t) / nin;
2439 }
2440
2441 // Factor for this type does not match another type, can not replicate
2442 if (f != (in.get(*t) / nin)) {
2443 can_replicate = false;
2444 break;
2445 }
2446 }
2447
2448 if (can_replicate && f > 0) {
2449 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2450 out.set (*t, outputs.get(*t) * f);
2451 }
2452 out += midi_bypass;
2453 return Match (Replicate, f);
2454 }
2455
2456 /* If the processor has exactly one input of a given type, and
2457 the plugin has more, we can feed the single processor input
2458 to some or all of the plugin inputs. This is rather
2459 special-case-y, but the 1-to-many case is by far the
2460 simplest. How do I split thy 2 processor inputs to 3
2461 plugin inputs? Let me count the ways ...
2462 */
2463
2464 bool can_split = true;
2465 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2466
2467 bool const can_split_type = (in.get (*t) == 1 && ns_inputs.get (*t) > 1);
2468 bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
2469
2470 if (!can_split_type && !nothing_to_do_for_type) {
2471 can_split = false;
2472 }
2473 }
2474
2475 if (can_split) {
2476 out = outputs + midi_bypass;
2477 return Match (Split, 1);
2478 }
2479
2480 /* If the plugin has more inputs than we want, we can `hide' some of them
2481 by feeding them silence.
2482 */
2483
2484 bool could_hide = false;
2485 bool cannot_hide = false;
2486 ChanCount hide_channels;
2487
2488 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
2489 if (inputs.get(*t) > in.get(*t)) {
2490 /* there is potential to hide, since the plugin has more inputs of type t than the insert */
2491 hide_channels.set (*t, inputs.get(*t) - in.get(*t));
2492 could_hide = true;
2493 } else if (inputs.get(*t) < in.get(*t)) {
2494 /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
2495 cannot_hide = true;
2496 }
2497 }
2498
2499 if (could_hide && !cannot_hide) {
2500 out = outputs + midi_bypass;
2501 return Match (Hide, 1, false, false, hide_channels);
2502 }
2503
2504 return Match (Impossible, 0);
2505 }
2506
2507
2508 XMLNode&
state()2509 PluginInsert::state ()
2510 {
2511 XMLNode& node = Processor::state ();
2512
2513 node.set_property("type", _plugins[0]->state_node_name());
2514 node.set_property("unique-id", _plugins[0]->unique_id());
2515 node.set_property("count", (uint32_t)_plugins.size());
2516
2517 /* remember actual i/o configuration (for later placeholder
2518 * in case the plugin goes missing) */
2519 node.add_child_nocopy (* _configured_in.state (X_("ConfiguredInput")));
2520 node.add_child_nocopy (* _custom_sinks.state (X_("CustomSinks")));
2521 node.add_child_nocopy (* _configured_out.state (X_("ConfiguredOutput")));
2522 node.add_child_nocopy (* _preset_out.state (X_("PresetOutput")));
2523
2524 /* save custom i/o config */
2525 node.set_property("custom", _custom_cfg);
2526 for (uint32_t pc = 0; pc < get_count(); ++pc) {
2527 char tmp[128];
2528 snprintf (tmp, sizeof(tmp), "InputMap-%d", pc);
2529 node.add_child_nocopy (* _in_map[pc].state (tmp));
2530 snprintf (tmp, sizeof(tmp), "OutputMap-%d", pc);
2531 node.add_child_nocopy (* _out_map[pc].state (tmp));
2532 }
2533 node.add_child_nocopy (* _thru_map.state ("ThruMap"));
2534
2535 if (_sidechain) {
2536 node.add_child_nocopy (_sidechain->get_state ());
2537 }
2538
2539 _plugins[0]->set_insert_id(this->id());
2540 node.add_child_nocopy (_plugins[0]->get_state());
2541
2542 for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
2543 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> ((*c).second);
2544 if (ac) {
2545 node.add_child_nocopy (ac->get_state());
2546 }
2547 }
2548
2549 return node;
2550 }
2551
2552 void
set_control_ids(const XMLNode & node,int version)2553 PluginInsert::set_control_ids (const XMLNode& node, int version)
2554 {
2555 const XMLNodeList& nlist = node.children();
2556 for (XMLNodeConstIterator iter = nlist.begin(); iter != nlist.end(); ++iter) {
2557 if ((*iter)->name() != Controllable::xml_node_name) {
2558 continue;
2559 }
2560
2561 uint32_t p = (uint32_t)-1;
2562 std::string str;
2563 if ((*iter)->get_property (X_("symbol"), str)) {
2564 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2565 if (lv2plugin) {
2566 p = lv2plugin->port_index(str.c_str());
2567 }
2568 }
2569 if (p == (uint32_t)-1) {
2570 (*iter)->get_property (X_("parameter"), p);
2571 }
2572
2573 if (p == (uint32_t)-1) {
2574 continue;
2575 }
2576
2577 /* this may create the new controllable */
2578 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p));
2579
2580 if (!c) {
2581 continue;
2582 }
2583 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2584 if (ac) {
2585 ac->set_state (**iter, version);
2586 }
2587 }
2588 }
2589
2590 void
update_control_values(const XMLNode & node,int version)2591 PluginInsert::update_control_values (const XMLNode& node, int version)
2592 {
2593 const XMLNodeList& nlist = node.children();
2594 for (XMLNodeConstIterator iter = nlist.begin(); iter != nlist.end(); ++iter) {
2595 if ((*iter)->name() != Controllable::xml_node_name) {
2596 continue;
2597 }
2598
2599 float val;
2600 if (!(*iter)->get_property (X_("value"), val)) {
2601 continue;
2602 }
2603
2604 uint32_t p = (uint32_t)-1;
2605
2606 std::string str;
2607 if ((*iter)->get_property (X_("symbol"), str)) {
2608 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugins[0]);
2609 if (lv2plugin) {
2610 p = lv2plugin->port_index(str.c_str());
2611 }
2612 }
2613
2614 if (p == (uint32_t)-1) {
2615 (*iter)->get_property (X_("parameter"), p);
2616 }
2617
2618 if (p == (uint32_t)-1) {
2619 continue;
2620 }
2621
2622 /* lookup controllable */
2623 boost::shared_ptr<Evoral::Control> c = control (Evoral::Parameter (PluginAutomation, 0, p), false);
2624 if (!c) {
2625 continue;
2626 }
2627 boost::shared_ptr<AutomationControl> ac = boost::dynamic_pointer_cast<AutomationControl> (c);
2628 if (ac) {
2629 ac->set_value (val, Controllable::NoGroup);
2630 }
2631 }
2632 }
2633
2634 int
set_state(const XMLNode & node,int version)2635 PluginInsert::set_state(const XMLNode& node, int version)
2636 {
2637 XMLNodeList nlist = node.children();
2638 XMLNodeIterator niter;
2639 XMLPropertyList plist;
2640 ARDOUR::PluginType type;
2641
2642 std::string str;
2643 if (!node.get_property ("type", str)) {
2644 error << _("XML node describing plugin is missing the `type' field") << endmsg;
2645 return -1;
2646 }
2647
2648 if (str == X_("ladspa") || str == X_("Ladspa")) { /* handle old school sessions */
2649 type = ARDOUR::LADSPA;
2650 } else if (str == X_("lv2")) {
2651 type = ARDOUR::LV2;
2652 } else if (str == X_("windows-vst")) {
2653 type = ARDOUR::Windows_VST;
2654 } else if (str == X_("lxvst")) {
2655 type = ARDOUR::LXVST;
2656 } else if (str == X_("mac-vst")) {
2657 type = ARDOUR::MacVST;
2658 } else if (str == X_("audiounit")) {
2659 type = ARDOUR::AudioUnit;
2660 } else if (str == X_("luaproc")) {
2661 type = ARDOUR::Lua;
2662 } else if (str == X_("vst3")) {
2663 type = ARDOUR::VST3;
2664 } else {
2665 error << string_compose (_("unknown plugin type %1 in plugin insert state"), str) << endmsg;
2666 return -1;
2667 }
2668
2669 XMLProperty const* prop = node.property ("unique-id");
2670
2671 if (prop == 0) {
2672 #ifdef WINDOWS_VST_SUPPORT
2673 /* older sessions contain VST plugins with only an "id" field. */
2674 if (type == ARDOUR::Windows_VST) {
2675 prop = node.property ("id");
2676 }
2677 #endif
2678
2679 #ifdef LXVST_SUPPORT
2680 /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
2681 if (type == ARDOUR::LXVST) {
2682 prop = node.property ("id");
2683 }
2684 #endif
2685
2686 /* recheck */
2687 if (prop == 0) {
2688 error << _("Plugin has no unique ID field") << endmsg;
2689 return -1;
2690 }
2691 }
2692
2693 bool any_vst = false;
2694 uint32_t count = 1;
2695 node.get_property ("count", count);
2696
2697 if (_plugins.empty()) {
2698 /* Find and load plugin module */
2699 boost::shared_ptr<Plugin> plugin = find_plugin (_session, prop->value(), type);
2700
2701 /* treat VST plugins equivalent if they have the same uniqueID
2702 * allow to move sessions windows <> linux */
2703 #ifdef LXVST_SUPPORT
2704 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::MacVST)) {
2705 type = ARDOUR::LXVST;
2706 plugin = find_plugin (_session, prop->value(), type);
2707 if (plugin) { any_vst = true; }
2708 }
2709 #endif
2710
2711 #ifdef WINDOWS_VST_SUPPORT
2712 if (plugin == 0 && (type == ARDOUR::LXVST || type == ARDOUR::MacVST)) {
2713 type = ARDOUR::Windows_VST;
2714 plugin = find_plugin (_session, prop->value(), type);
2715 if (plugin) { any_vst = true; }
2716 }
2717 #endif
2718
2719 #ifdef MACVST_SUPPORT
2720 if (plugin == 0 && (type == ARDOUR::Windows_VST || type == ARDOUR::LXVST)) {
2721 type = ARDOUR::MacVST;
2722 plugin = find_plugin (_session, prop->value(), type);
2723 if (plugin) { any_vst = true; }
2724 }
2725 #endif
2726
2727 if (plugin == 0 && type == ARDOUR::Lua) {
2728 /* unique ID (sha1 of script) was not found,
2729 * load the plugin from the serialized version in the
2730 * session-file instead.
2731 */
2732 boost::shared_ptr<LuaProc> lp (new LuaProc (_session.engine(), _session, ""));
2733 XMLNode *ls = node.child (lp->state_node_name().c_str());
2734 if (ls && lp) {
2735 if (0 == lp->set_script_from_state (*ls)) {
2736 plugin = lp;
2737 }
2738 }
2739 }
2740
2741 if (plugin == 0) {
2742 error << string_compose(
2743 _("Found a reference to a plugin (\"%1\") that is unknown.\n"
2744 "Perhaps it was removed or moved since it was last used."),
2745 prop->value())
2746 << endmsg;
2747 return -1;
2748 }
2749
2750 /* The name of the PluginInsert comes from the plugin */
2751 _name = plugin->get_info()->name;
2752
2753 /* Processor::set_state() will set this, but too late
2754 * for it to be available when setting up plugin
2755 * state. We can't call Processor::set_state() until
2756 * the plugins themselves are created and added.
2757 */
2758
2759 set_id (node);
2760
2761 /* if we are adding the first plugin, we will need to set
2762 * up automatable controls.
2763 */
2764 add_plugin (plugin);
2765 create_automatable_parameters ();
2766 set_control_ids (node, version);
2767
2768 if (_plugins.size() != count) {
2769 for (uint32_t n = 1; n < count; ++n) {
2770 add_plugin (plugin_factory (plugin));
2771 }
2772 }
2773 } else {
2774 assert (_plugins[0]->unique_id() == prop->value());
2775 /* update controllable value only (copy plugin state) */
2776 set_id (node);
2777 update_control_values (node, version);
2778 }
2779
2780 Processor::set_state (node, version);
2781
2782 PBD::ID new_id = this->id();
2783 PBD::ID old_id = this->id();
2784
2785 node.get_property ("id", old_id);
2786
2787 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2788 /* find the node with the type-specific node name ("lv2", "ladspa", etc)
2789 * and set all plugins to the same state.
2790 */
2791 if ((*niter)->name() == _plugins[0]->state_node_name ()
2792 || (any_vst && ((*niter)->name() == "lxvst" || (*niter)->name() == "windows-vst" || (*niter)->name() == "mac-vst"))
2793 ) {
2794
2795 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2796 /* Plugin state can include external files which are named after the ID.
2797 *
2798 * If regenerate_xml_or_string_ids() is set, the ID will already have
2799 * been changed, so we need to use the old ID from the XML to load the
2800 * state and then update the ID.
2801 *
2802 * When copying a plugin-state, route_ui takes care of of updating the ID,
2803 * but we need to call set_insert_id() to clear the cached plugin-state
2804 * and force a change.
2805 */
2806 if (!regenerate_xml_or_string_ids ()) {
2807 (*i)->set_insert_id (new_id);
2808 } else {
2809 (*i)->set_insert_id (old_id);
2810 }
2811
2812 (*i)->set_state (**niter, version);
2813
2814 if (regenerate_xml_or_string_ids ()) {
2815 (*i)->set_insert_id (new_id);
2816 }
2817 }
2818
2819 /* when copying plugin state, notify UI */
2820 for (Controls::const_iterator li = controls().begin(); li != controls().end(); ++li) {
2821 boost::shared_ptr<PBD::Controllable> c = boost::dynamic_pointer_cast<PBD::Controllable> (li->second);
2822 if (c) {
2823 c->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
2824 }
2825 }
2826
2827 break;
2828 }
2829 }
2830
2831 if (version < 3000) {
2832
2833 /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
2834 this is all handled by Automatable
2835 */
2836
2837 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2838 if ((*niter)->name() == "Redirect") {
2839 /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
2840 Processor::set_state (**niter, version);
2841 break;
2842 }
2843 }
2844
2845 set_parameter_state_2X (node, version);
2846 }
2847
2848 node.get_property (X_("custom"), _custom_cfg);
2849
2850 uint32_t in_maps = 0;
2851 uint32_t out_maps = 0;
2852 XMLNodeList kids = node.children ();
2853 for (XMLNodeIterator i = kids.begin(); i != kids.end(); ++i) {
2854 if ((*i)->name() == X_("ConfiguredInput")) {
2855 _configured_in = ChanCount(**i);
2856 }
2857 if ((*i)->name() == X_("CustomSinks")) {
2858 _custom_sinks = ChanCount(**i);
2859 }
2860 if ((*i)->name() == X_("ConfiguredOutput")) {
2861 _custom_out = ChanCount(**i);
2862 _configured_out = ChanCount(**i);
2863 }
2864 if ((*i)->name() == X_("PresetOutput")) {
2865 _preset_out = ChanCount(**i);
2866 }
2867 if (strncmp ((*i)->name ().c_str(), X_("InputMap-"), 9) == 0) {
2868 long pc = atol (&((*i)->name().c_str()[9]));
2869 if (pc >= 0 && pc <= (long) get_count()) {
2870 _in_map[pc] = ChanMapping (**i);
2871 ++in_maps;
2872 }
2873 }
2874 if (strncmp ((*i)->name ().c_str(), X_("OutputMap-"), 10) == 0) {
2875 long pc = atol (&((*i)->name().c_str()[10]));
2876 if (pc >= 0 && pc <= (long) get_count()) {
2877 _out_map[pc] = ChanMapping (**i);
2878 ++out_maps;
2879 }
2880 }
2881 if ((*i)->name () == "ThruMap") {
2882 _thru_map = ChanMapping (**i);
2883 }
2884
2885 // sidechain is a Processor (IO)
2886 if ((*i)->name () == Processor::state_node_name) {
2887 if (!_sidechain) {
2888 if (regenerate_xml_or_string_ids ()) {
2889 add_sidechain_from_xml (**i, version);
2890 } else {
2891 add_sidechain (0);
2892 }
2893 }
2894 if (!regenerate_xml_or_string_ids ()) {
2895 _sidechain->set_state (**i, version);
2896 } else {
2897 update_sidechain_name ();
2898 }
2899 }
2900 }
2901
2902 if (in_maps == out_maps && out_maps >0 && out_maps == get_count()) {
2903 _maps_from_state = true;
2904 }
2905
2906 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2907 if (active()) {
2908 (*i)->activate ();
2909 } else {
2910 (*i)->deactivate ();
2911 }
2912 }
2913
2914 PluginConfigChanged (); /* EMIT SIGNAL */
2915 return 0;
2916 }
2917
2918 void
update_id(PBD::ID id)2919 PluginInsert::update_id (PBD::ID id)
2920 {
2921 set_id (id.to_s());
2922 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2923 (*i)->set_insert_id (id);
2924 }
2925 }
2926
2927 void
set_owner(SessionObject * o)2928 PluginInsert::set_owner (SessionObject* o)
2929 {
2930 Processor::set_owner (o);
2931 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
2932 (*i)->set_owner (o);
2933 }
2934 }
2935
2936 void
set_state_dir(const std::string & d)2937 PluginInsert::set_state_dir (const std::string& d)
2938 {
2939 // state() only saves the state of the first plugin
2940 _plugins[0]->set_state_dir (d);
2941 }
2942
2943 void
set_parameter_state_2X(const XMLNode & node,int version)2944 PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
2945 {
2946 XMLNodeList nlist = node.children();
2947 XMLNodeIterator niter;
2948
2949 /* look for port automation node */
2950
2951 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2952
2953 if ((*niter)->name() != port_automation_node_name) {
2954 continue;
2955 }
2956
2957 XMLNodeList cnodes;
2958 XMLNodeConstIterator iter;
2959 XMLNode *child;
2960 uint32_t port_id;
2961
2962 cnodes = (*niter)->children ("port");
2963
2964 for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
2965
2966 child = *iter;
2967
2968 if (!child->get_property("number", port_id)) {
2969 warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
2970 continue;
2971 }
2972
2973 if (port_id >= _plugins[0]->parameter_count()) {
2974 warning << _("PluginInsert: Auto: port id out of range") << endmsg;
2975 continue;
2976 }
2977
2978 boost::shared_ptr<AutomationControl> c = boost::dynamic_pointer_cast<AutomationControl>(
2979 control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
2980
2981 if (c && c->alist()) {
2982 if (!child->children().empty()) {
2983 c->alist()->set_state (*child->children().front(), version);
2984 }
2985 } else {
2986 error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
2987 }
2988 }
2989
2990 /* done */
2991
2992 break;
2993 }
2994 }
2995
2996 boost::shared_ptr<ReadOnlyControl>
control_output(uint32_t num) const2997 PluginInsert::control_output (uint32_t num) const
2998 {
2999 CtrlOutMap::const_iterator i = _control_outputs.find (num);
3000 if (i == _control_outputs.end ()) {
3001 return boost::shared_ptr<ReadOnlyControl> ();
3002 } else {
3003 return (*i).second;
3004 }
3005 }
3006
3007 string
describe_parameter(Evoral::Parameter param)3008 PluginInsert::describe_parameter (Evoral::Parameter param)
3009 {
3010 if (param.type() == PluginAutomation) {
3011 return _plugins[0]->describe_parameter (param);
3012 } else if (param.type() == PluginPropertyAutomation) {
3013 boost::shared_ptr<AutomationControl> c(automation_control(param));
3014 if (c && !c->desc().label.empty()) {
3015 return c->desc().label;
3016 }
3017 }
3018 return Automatable::describe_parameter(param);
3019 }
3020
3021 ARDOUR::samplecnt_t
signal_latency() const3022 PluginInsert::signal_latency() const
3023 {
3024 if (!_pending_active) {
3025 return 0;
3026 }
3027 return plugin_latency ();
3028 }
3029
3030 ARDOUR::PluginType
type() const3031 PluginInsert::type () const
3032 {
3033 return plugin()->get_info()->type;
3034 }
3035
PluginControl(PluginInsert * p,const Evoral::Parameter & param,const ParameterDescriptor & desc,boost::shared_ptr<AutomationList> list)3036 PluginInsert::PluginControl::PluginControl (PluginInsert* p,
3037 const Evoral::Parameter& param,
3038 const ParameterDescriptor& desc,
3039 boost::shared_ptr<AutomationList> list)
3040 : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
3041 , _plugin (p)
3042 {
3043 if (alist()) {
3044 if (desc.toggled) {
3045 list->set_interpolation(Evoral::ControlList::Discrete);
3046 }
3047 }
3048 }
3049
3050 /** @param val `user' value */
3051
3052 void
actually_set_value(double user_val,PBD::Controllable::GroupControlDisposition group_override)3053 PluginInsert::PluginControl::actually_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
3054 {
3055 /* FIXME: probably should be taking out some lock here.. */
3056
3057 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3058 (*i)->set_parameter (_list->parameter().id(), user_val, 0);
3059 }
3060
3061 boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
3062 if (iasp) {
3063 iasp->set_parameter (_list->parameter().id(), user_val, 0);
3064 }
3065
3066 AutomationControl::actually_set_value (user_val, group_override);
3067 }
3068
3069 void
catch_up_with_external_value(double user_val)3070 PluginInsert::PluginControl::catch_up_with_external_value (double user_val)
3071 {
3072 AutomationControl::actually_set_value (user_val, Controllable::NoGroup);
3073 }
3074
3075 XMLNode&
get_state()3076 PluginInsert::PluginControl::get_state ()
3077 {
3078 XMLNode& node (AutomationControl::get_state());
3079 node.set_property (X_("parameter"), parameter().id());
3080
3081 boost::shared_ptr<LV2Plugin> lv2plugin = boost::dynamic_pointer_cast<LV2Plugin> (_plugin->_plugins[0]);
3082 if (lv2plugin) {
3083 node.set_property (X_("symbol"), lv2plugin->port_symbol (parameter().id()));
3084 }
3085
3086 return node;
3087 }
3088
3089 /** @return `user' val */
3090 double
get_value() const3091 PluginInsert::PluginControl::get_value () const
3092 {
3093 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
3094
3095 if (!plugin) {
3096 return 0.0;
3097 }
3098
3099 return plugin->get_parameter (_list->parameter().id());
3100 }
3101
3102 std::string
get_user_string() const3103 PluginInsert::PluginControl::get_user_string () const
3104 {
3105 boost::shared_ptr<Plugin> plugin = _plugin->plugin (0);
3106 if (plugin) {
3107 std::string pp;
3108 if (plugin->print_parameter (parameter().id(), pp) && pp.size () > 0) {
3109 return pp;
3110 }
3111 }
3112 return AutomationControl::get_user_string ();
3113 }
3114
PluginPropertyControl(PluginInsert * p,const Evoral::Parameter & param,const ParameterDescriptor & desc,boost::shared_ptr<AutomationList> list)3115 PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert* p,
3116 const Evoral::Parameter& param,
3117 const ParameterDescriptor& desc,
3118 boost::shared_ptr<AutomationList> list)
3119 : AutomationControl (p->session(), param, desc, list)
3120 , _plugin (p)
3121 {
3122 }
3123
3124 void
actually_set_value(double user_val,Controllable::GroupControlDisposition gcd)3125 PluginInsert::PluginPropertyControl::actually_set_value (double user_val, Controllable::GroupControlDisposition gcd)
3126 {
3127 /* Old numeric set_value(), coerce to appropriate datatype if possible.
3128 This is lossy, but better than nothing until Ardour's automation system
3129 can handle various datatypes all the way down. */
3130 const Variant value(_desc.datatype, user_val);
3131 if (value.type() == Variant::NOTHING) {
3132 error << "set_value(double) called for non-numeric property" << endmsg;
3133 return;
3134 }
3135
3136 for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
3137 (*i)->set_property(_list->parameter().id(), value);
3138 }
3139
3140 _value = value;
3141
3142 AutomationControl::actually_set_value (user_val, gcd);
3143 }
3144
3145 XMLNode&
get_state()3146 PluginInsert::PluginPropertyControl::get_state ()
3147 {
3148 XMLNode& node (AutomationControl::get_state());
3149 node.set_property (X_("property"), parameter().id());
3150 node.remove_property (X_("value"));
3151
3152 return node;
3153 }
3154
3155 double
get_value() const3156 PluginInsert::PluginPropertyControl::get_value () const
3157 {
3158 return _value.to_double();
3159 }
3160
3161 boost::shared_ptr<Plugin>
get_impulse_analysis_plugin()3162 PluginInsert::get_impulse_analysis_plugin()
3163 {
3164 boost::shared_ptr<Plugin> ret;
3165 if (_impulseAnalysisPlugin.expired()) {
3166 // LV2 in particular uses various _session params
3167 // during init() -- most notably block_size..
3168 // not great.
3169 ret = plugin_factory(_plugins[0]);
3170 ret->use_for_impulse_analysis ();
3171 ChanCount ins = internal_input_streams ();
3172 ChanCount out (internal_output_streams ());
3173 ChanCount aux_in;
3174 if (ret->get_info ()->reconfigurable_io ()) {
3175 // populate get_info ()->n_inputs and ->n_outputs
3176 ret->match_variable_io (ins, aux_in, out);
3177 assert (out == internal_output_streams ());
3178 }
3179 ret->reconfigure_io (ins, aux_in, out);
3180 ret->set_owner (_owner);
3181 _impulseAnalysisPlugin = ret;
3182
3183 _plugins[0]->add_slave (ret, false);
3184 ret->DropReferences.connect_same_thread (*this, boost::bind (&PluginInsert::plugin_removed, this, _impulseAnalysisPlugin));
3185 } else {
3186 ret = _impulseAnalysisPlugin.lock();
3187 }
3188
3189 return ret;
3190 }
3191
3192 void
collect_signal_for_analysis(samplecnt_t nframes)3193 PluginInsert::collect_signal_for_analysis (samplecnt_t nframes)
3194 {
3195 if (_signal_analysis_collect_nsamples_max != 0
3196 || _signal_analysis_collect_nsamples != 0) {
3197 return;
3198 }
3199
3200 // called from outside the audio thread, so this should be safe
3201 // only do audio as analysis is (currently) only for audio plugins
3202 _signal_analysis_inputs.ensure_buffers (DataType::AUDIO, input_streams().n_audio(), nframes);
3203 _signal_analysis_outputs.ensure_buffers (DataType::AUDIO, output_streams().n_audio(), nframes);
3204
3205 /* these however should not be set while processing,
3206 * however in the given order, this should be fine.
3207 */
3208 _signal_analysis_collect_nsamples = 0;
3209 _signal_analysis_collect_nsamples_max = nframes;
3210 }
3211
3212 /** Add a plugin to our list */
3213 void
add_plugin(boost::shared_ptr<Plugin> plugin)3214 PluginInsert::add_plugin (boost::shared_ptr<Plugin> plugin)
3215 {
3216 plugin->set_insert_id (this->id());
3217 plugin->set_owner (_owner);
3218
3219 if (_plugins.empty()) {
3220 /* first (and probably only) plugin instance - connect to relevant signals */
3221
3222 plugin->ParameterChangedExternally.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed_externally, this, _1, _2));
3223 plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
3224 plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
3225 _custom_sinks = plugin->get_info()->n_inputs;
3226 // cache sidechain port count
3227 _cached_sidechain_pins.reset ();
3228 const ChanCount& nis (plugin->get_info()->n_inputs);
3229 for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
3230 for (uint32_t in = 0; in < nis.get (*t); ++in) {
3231 const Plugin::IOPortDescription& iod (plugin->describe_io_port (*t, true, in));
3232 if (iod.is_sidechain) {
3233 _cached_sidechain_pins.set (*t, 1 + _cached_sidechain_pins.n(*t));
3234 }
3235 }
3236 }
3237 }
3238 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
3239 boost::shared_ptr<VSTPlugin> vst = boost::dynamic_pointer_cast<VSTPlugin> (plugin);
3240 if (vst) {
3241 vst->set_insert (this, _plugins.size ());
3242 }
3243 #endif
3244
3245 _plugins.push_back (plugin);
3246
3247 if (_plugins.size() > 1) {
3248 _plugins[0]->add_slave (plugin, true);
3249 plugin->DropReferences.connect_same_thread (*this, boost::bind (&PluginInsert::plugin_removed, this, boost::weak_ptr<Plugin> (plugin)));
3250 }
3251 }
3252
3253 void
plugin_removed(boost::weak_ptr<Plugin> wp)3254 PluginInsert::plugin_removed (boost::weak_ptr<Plugin> wp)
3255 {
3256 boost::shared_ptr<Plugin> plugin = wp.lock();
3257 if (_plugins.size () == 0 || !plugin) {
3258 return;
3259 }
3260 _plugins[0]->remove_slave (plugin);
3261 }
3262
3263 void
add_sidechain_from_xml(const XMLNode & node,int version)3264 PluginInsert::add_sidechain_from_xml (const XMLNode& node, int version)
3265 {
3266 if (version < 3000) {
3267 return;
3268 }
3269
3270 XMLNodeList nlist = node.children();
3271
3272 if (nlist.size() == 0) {
3273 return;
3274 }
3275
3276 uint32_t audio = 0;
3277 uint32_t midi = 0;
3278
3279 XMLNodeConstIterator it = nlist.front()->children().begin();
3280 for ( ; it != nlist.front()->children().end(); ++ it) {
3281 if ((*it)->name() == "Port") {
3282 DataType type(DataType::NIL);
3283 (*it)->get_property ("type", type);
3284 if (type == DataType::AUDIO) {
3285 ++audio;
3286 } else if (type == DataType::MIDI) {
3287 ++midi;
3288 }
3289 }
3290 }
3291
3292 ChanCount in_cc = ChanCount();
3293 in_cc.set (DataType::AUDIO, audio);
3294 in_cc.set (DataType::MIDI, midi);
3295
3296 add_sidechain (audio, midi);
3297 }
3298
3299 bool
load_preset(ARDOUR::Plugin::PresetRecord pr)3300 PluginInsert::load_preset (ARDOUR::Plugin::PresetRecord pr)
3301 {
3302 bool ok = true;
3303 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3304 if (! (*i)->load_preset (pr)) {
3305 ok = false;
3306 }
3307 }
3308
3309 boost::shared_ptr<Plugin> iasp = _impulseAnalysisPlugin.lock();
3310 if (iasp) {
3311 iasp->load_preset (pr);
3312 }
3313
3314 return ok;
3315 }
3316
3317 void
realtime_handle_transport_stopped()3318 PluginInsert::realtime_handle_transport_stopped ()
3319 {
3320 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3321 (*i)->realtime_handle_transport_stopped ();
3322 }
3323 }
3324
3325 void
realtime_locate(bool for_loop_end)3326 PluginInsert::realtime_locate (bool for_loop_end)
3327 {
3328 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3329 (*i)->realtime_locate (for_loop_end);
3330 }
3331 }
3332
3333 void
monitoring_changed()3334 PluginInsert::monitoring_changed ()
3335 {
3336 for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
3337 (*i)->monitoring_changed ();
3338 }
3339 }
3340
3341 void
latency_changed()3342 PluginInsert::latency_changed ()
3343 {
3344 // this is called in RT context, LatencyChanged is emitted after run()
3345 _latency_changed = true;
3346 LatencyChanged (); /* EMIT SIGNAL */
3347 // XXX This needs a proper API not an owner() hack:
3348 // TODO Route should subscribe to LatencyChanged() and forward it
3349 // to the session as processor_latency_changed.
3350 assert (owner ());
3351 static_cast<Route*>(owner ())->processor_latency_changed (); /* EMIT SIGNAL */
3352 }
3353
3354 void
start_touch(uint32_t param_id)3355 PluginInsert::start_touch (uint32_t param_id)
3356 {
3357 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3358 if (ac) {
3359 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3360 ac->start_touch (session().audible_sample());
3361 }
3362 }
3363
3364 void
end_touch(uint32_t param_id)3365 PluginInsert::end_touch (uint32_t param_id)
3366 {
3367 boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, param_id));
3368 if (ac) {
3369 // ToDo subtract _plugin_signal_latency from audible_sample() when rolling, assert > 0
3370 ac->stop_touch (session().audible_sample());
3371 }
3372 }
3373
3374 bool
provides_stats() const3375 PluginInsert::provides_stats () const
3376 {
3377 #if defined MIXBUS && defined NDEBUG
3378 if (is_channelstrip () || !display_to_user ()) {
3379 return false;
3380 }
3381 #endif
3382 return true;
3383 }
3384
3385 bool
get_stats(PBD::microseconds_t & min,PBD::microseconds_t & max,double & avg,double & dev) const3386 PluginInsert::get_stats (PBD::microseconds_t& min, PBD::microseconds_t& max, double& avg, double& dev) const
3387 {
3388 /* TODO: consider taking a try/lock: Don't run concurrently with
3389 * TimingStats::update, TimingStats::reset.
3390 */
3391 return _timing_stats.get_stats (min, max, avg, dev);
3392 }
3393
3394 void
clear_stats()3395 PluginInsert::clear_stats ()
3396 {
3397 g_atomic_int_set (&_stat_reset, 1);
3398 }
3399
operator <<(std::ostream & o,const ARDOUR::PluginInsert::Match & m)3400 std::ostream& operator<<(std::ostream& o, const ARDOUR::PluginInsert::Match& m)
3401 {
3402 switch (m.method) {
3403 case PluginInsert::Impossible: o << "Impossible"; break;
3404 case PluginInsert::Delegate: o << "Delegate"; break;
3405 case PluginInsert::NoInputs: o << "NoInputs"; break;
3406 case PluginInsert::ExactMatch: o << "ExactMatch"; break;
3407 case PluginInsert::Replicate: o << "Replicate"; break;
3408 case PluginInsert::Split: o << "Split"; break;
3409 case PluginInsert::Hide: o << "Hide"; break;
3410 }
3411 o << " cnt: " << m.plugins
3412 << (m.strict_io ? " strict-io" : "")
3413 << (m.custom_cfg ? " custom-cfg" : "");
3414 if (m.method == PluginInsert::Hide) {
3415 o << " hide: " << m.hide;
3416 }
3417 o << "\n";
3418 return o;
3419 }
3420