ardour
plugin_insert.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23 
24 #include <string>
25 
26 #include "pbd/failed_constructor.h"
27 #include "pbd/xml++.h"
28 #include "pbd/convert.h"
29 
30 #include "ardour/audio_buffer.h"
31 #include "ardour/automation_list.h"
32 #include "ardour/buffer_set.h"
33 #include "ardour/debug.h"
34 #include "ardour/event_type_map.h"
35 #include "ardour/ladspa_plugin.h"
36 #include "ardour/plugin.h"
37 #include "ardour/plugin_insert.h"
38 
39 #ifdef LV2_SUPPORT
40 #include "ardour/lv2_plugin.h"
41 #endif
42 
43 #ifdef WINDOWS_VST_SUPPORT
45 #endif
46 
47 #ifdef LXVST_SUPPORT
48 #include "ardour/lxvst_plugin.h"
49 #endif
50 
51 #ifdef AUDIOUNIT_SUPPORT
52 #include "ardour/audio_unit.h"
53 #endif
54 
55 #include "ardour/session.h"
56 #include "ardour/types.h"
57 
58 #include "i18n.h"
59 
60 using namespace std;
61 using namespace ARDOUR;
62 using namespace PBD;
63 
64 const string PluginInsert::port_automation_node_name = "PortAutomation";
65 
66 PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
67  : Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
68  , _signal_analysis_collected_nframes(0)
69  , _signal_analysis_collect_nframes_max(0)
70 {
71  /* the first is the master */
72 
73  if (plug) {
74  add_plugin (plug);
76  }
77 }
78 
79 bool
81 {
82  bool require_state = !_plugins.empty();
83 
84  /* this is a bad idea.... we shouldn't do this while active.
85  only a route holding their redirect_lock should be calling this
86  */
87 
88  if (num == 0) {
89  return false;
90  } else if (num > _plugins.size()) {
91  uint32_t diff = num - _plugins.size();
92 
93  for (uint32_t n = 0; n < diff; ++n) {
95  add_plugin (p);
96  if (active ()) {
97  p->activate ();
98  }
99 
100  if (require_state) {
101  /* XXX do something */
102  }
103  }
104 
105  } else if (num < _plugins.size()) {
106  uint32_t diff = _plugins.size() - num;
107  for (uint32_t n= 0; n < diff; ++n) {
108  _plugins.pop_back();
109  }
110  }
111 
112  return true;
113 }
114 
116 {
117 }
118 
119 void
121 {
122  if (which.type() != PluginAutomation)
123  return;
124 
127 
128  if (c && s != Off) {
129  _plugins[0]->set_parameter (which.id(), c->list()->eval (_session.transport_frame()));
130  }
131 }
132 
133 ChanCount
135 {
136  assert (!_plugins.empty());
137 
138  PluginInfoPtr info = _plugins.front()->get_info();
139 
140  if (info->reconfigurable_io()) {
141  ChanCount out = _plugins.front()->output_streams ();
142  // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, reconfigur(able) output streams = %1\n", out));
143  return out;
144  } else {
145  ChanCount out = info->n_outputs;
146  // DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, static output streams = %1 for %2 plugins\n", out, _plugins.size()));
147  out.set_audio (out.n_audio() * _plugins.size());
148  out.set_midi (out.n_midi() * _plugins.size() + midi_bypass.n_midi());
149  return out;
150  }
151 }
152 
153 ChanCount
155 {
156  assert (!_plugins.empty());
157 
158  ChanCount in;
159 
160  PluginInfoPtr info = _plugins.front()->get_info();
161 
162  if (info->reconfigurable_io()) {
163  assert (_plugins.size() == 1);
164  in = _plugins.front()->input_streams();
165  } else {
166  in = info->n_inputs;
167  }
168 
169  DEBUG_TRACE (DEBUG::Processors, string_compose ("Plugin insert, input streams = %1, match using %2\n", in, _match.method));
170 
171  if (_match.method == Split) {
172 
173  /* we are splitting 1 processor input to multiple plugin inputs,
174  so we have a maximum of 1 stream of each type.
175  */
176  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
177  if (in.get (*t) > 1) {
178  in.set (*t, 1);
179  }
180  }
181  return in;
182 
183  } else if (_match.method == Hide) {
184 
185  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
186  in.set (*t, in.get (*t) - _match.hide.get (*t));
187  }
188  return in;
189 
190  } else {
191 
192  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
193  in.set (*t, in.get (*t) * _plugins.size ());
194  }
195 
196  return in;
197  }
198 }
199 
200 ChanCount
202 {
203  return _plugins[0]->get_info()->n_outputs;
204 }
205 
206 ChanCount
208 {
209  return _plugins[0]->get_info()->n_inputs;
210 }
211 
212 bool
214 {
215  return _plugins[0]->get_info()->n_inputs == ChanCount::ZERO;
216 }
217 
218 bool
220 {
221  return _plugins[0]->get_info()->n_inputs.n_audio() == 0;
222 }
223 
224 bool
226 {
227  /* XXX more finesse is possible here. VST plugins have a
228  a specific "instrument" flag, for example.
229  */
230  PluginInfoPtr pi = _plugins[0]->get_info();
231 
232  return pi->n_inputs.n_midi() != 0 &&
233  pi->n_outputs.n_audio() > 0;
234 }
235 
236 void
238 {
239  assert (!_plugins.empty());
240 
241  set<Evoral::Parameter> a = _plugins.front()->automatable ();
242 
243  for (set<Evoral::Parameter>::iterator i = a.begin(); i != a.end(); ++i) {
244  if (i->type() == PluginAutomation) {
245 
246  Evoral::Parameter param(*i);
247 
248  ParameterDescriptor desc;
249  _plugins.front()->get_parameter_descriptor(i->id(), desc);
250 
251  can_automate (param);
252  boost::shared_ptr<AutomationList> list(new AutomationList(param, desc));
253  add_control (boost::shared_ptr<AutomationControl> (new PluginControl(this, param, desc, list)));
254  } else if (i->type() == PluginPropertyAutomation) {
255  Evoral::Parameter param(*i);
256  const ParameterDescriptor& desc = _plugins.front()->get_property_descriptor(param.id());
257  if (desc.datatype != Variant::NOTHING) {
260  list = boost::shared_ptr<AutomationList>(new AutomationList(param, desc));
261  }
263  }
264  }
265  }
266 }
267 
268 void
269 PluginInsert::parameter_changed (uint32_t which, float val)
270 {
272 
273  if (ac) {
274  ac->set_value (val);
275 
276  Plugins::iterator i = _plugins.begin();
277 
278  /* don't set the first plugin, just all the slaves */
279 
280  if (i != _plugins.end()) {
281  ++i;
282  for (; i != _plugins.end(); ++i) {
283  (*i)->set_parameter (which, val);
284  }
285  }
286  }
287 }
288 
289 int
291 {
292  int ret = 0;
293  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
294  if ((*i)->set_block_size (nframes) != 0) {
295  ret = -1;
296  }
297  }
298  return ret;
299 }
300 
301 void
303 {
304  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
305  (*i)->activate ();
306  }
307 
309 }
310 
311 void
313 {
315 
316  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
317  (*i)->deactivate ();
318  }
319 }
320 
321 void
323 {
324  for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
325  (*i)->flush ();
326  }
327 }
328 
329 void
330 PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
331 {
332  // Calculate if, and how many frames we need to collect for analysis
333  framecnt_t collect_signal_nframes = (_signal_analysis_collect_nframes_max -
335  if (nframes < collect_signal_nframes) { // we might not get all frames now
336  collect_signal_nframes = nframes;
337  }
338 
339  ChanCount const in_streams = input_streams ();
340  ChanCount const out_streams = output_streams ();
341 
342  ChanMapping in_map (in_streams);
343  ChanMapping out_map (out_streams);
344  bool valid;
345  if (_match.method == Split) {
346  /* fix the input mapping so that we have maps for each of the plugin's inputs */
347  in_map = ChanMapping (natural_input_streams ());
348 
349  /* copy the first stream's buffer contents to the others */
350  /* XXX: audio only */
351  uint32_t first_idx = in_map.get (DataType::AUDIO, 0, &valid);
352  if (valid) {
353  for (uint32_t i = in_streams.n_audio(); i < natural_input_streams().n_audio(); ++i) {
354  bufs.get_audio(in_map.get (DataType::AUDIO, i, &valid)).read_from(bufs.get_audio(first_idx), nframes, offset, offset);
355  }
356  }
357  }
358 
359  bufs.set_count(ChanCount::max(bufs.count(), in_streams));
360  bufs.set_count(ChanCount::max(bufs.count(), out_streams));
361 
362  /* Note that we've already required that plugins
363  be able to handle in-place processing.
364  */
365 
366  if (with_auto) {
367 
368  uint32_t n = 0;
369 
370  for (Controls::iterator li = controls().begin(); li != controls().end(); ++li, ++n) {
371 
374 
375  if (c->list() && c->automation_playback()) {
376  bool valid;
377 
378  const float val = c->list()->rt_safe_eval (now, valid);
379 
380  if (valid) {
381  c->set_value(val);
382  }
383 
384  }
385  }
386  }
387 
388  if (collect_signal_nframes > 0) {
389  // collect input
390  //std::cerr << "collect input, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
391  //std::cerr << " streams " << input_streams().n_audio() << std::endl;
392  //std::cerr << "filling buffer with " << collect_signal_nframes << " frames at " << _signal_analysis_collected_nframes << std::endl;
393 
395 
396  for (uint32_t i = 0; i < input_streams().n_audio(); ++i) {
398  bufs.get_audio(i),
399  collect_signal_nframes,
400  _signal_analysis_collected_nframes); // offset is for target buffer
401  }
402 
403  }
404 
405  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
406  (*i)->connect_and_run(bufs, in_map, out_map, nframes, offset);
407  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
408  in_map.offset_to(*t, natural_input_streams().get(*t));
409  out_map.offset_to(*t, natural_output_streams().get(*t));
410  }
411  }
412 
413  if (collect_signal_nframes > 0) {
414  // collect output
415  //std::cerr << " output, bufs " << bufs.count().n_audio() << " count, " << bufs.available().n_audio() << " available" << std::endl;
416  //std::cerr << " streams " << output_streams().n_audio() << std::endl;
417 
419 
420  for (uint32_t i = 0; i < output_streams().n_audio(); ++i) {
422  bufs.get_audio(i),
423  collect_signal_nframes,
424  _signal_analysis_collected_nframes); // offset is for target buffer
425  }
426 
427  _signal_analysis_collected_nframes += collect_signal_nframes;
429 
433 
436  }
437  }
438  /* leave remaining channel buffers alone */
439 }
440 
441 void
443 {
444  if (!active ()) {
445  return;
446  }
447 
448  ChanMapping in_map(input_streams());
449  ChanMapping out_map(output_streams());
450 
451  if (_match.method == Split) {
452  /* fix the input mapping so that we have maps for each of the plugin's inputs */
453  in_map = ChanMapping (natural_input_streams ());
454  }
455 
456  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
457  (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
458  }
459 }
460 
461 void
462 PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t /*end_frame*/, pframes_t nframes, bool)
463 {
464  if (_pending_active) {
465  /* run as normal if we are active or moving from inactive to active */
466 
468  automation_run (bufs, start_frame, nframes);
469  } else {
470  connect_and_run (bufs, nframes, 0, false);
471  }
472 
473  } else {
474  uint32_t in = input_streams ().n_audio ();
475  uint32_t out = output_streams().n_audio ();
476 
477  if (has_no_audio_inputs() || in == 0) {
478 
479  /* silence all (audio) outputs. Should really declick
480  * at the transitions of "active"
481  */
482 
483  for (uint32_t n = 0; n < out; ++n) {
484  bufs.get_audio (n).silence (nframes);
485  }
486 
487  } else if (out > in) {
488 
489  /* not active, but something has make up for any channel count increase */
490 
491  // TODO: option round-robin (n % in) or silence additional buffers ??
492  // for now , simply replicate last buffer
493  for (uint32_t n = in; n < out; ++n) {
494  bufs.get_audio(n).read_from(bufs.get_audio(in - 1), nframes);
495  }
496  }
497 
498  bufs.count().set_audio (out);
499  }
500 
502 
503  /* we have no idea whether the plugin generated silence or not, so mark
504  * all buffers appropriately.
505  */
506 
507 }
508 
509 void
511 {
512  if (param.type() != PluginAutomation) {
513  return;
514  }
515 
516  /* the others will be set from the event triggered by this */
517 
518  _plugins[0]->set_parameter (param.id(), val);
519 
522 
523  if (ac) {
524  ac->set_value(val);
525  } else {
526  warning << "set_parameter called for nonexistant parameter "
527  << EventTypeMap::instance().to_symbol(param) << endmsg;
528  }
529 
531 }
532 
533 float
535 {
536  if (param.type() != PluginAutomation) {
537  return 0.0;
538  } else {
539  assert (!_plugins.empty ());
540  return _plugins[0]->get_parameter (param.id());
541  }
542 }
543 
544 void
546 {
547  Evoral::ControlEvent next_event (0, 0.0f);
548  framepos_t now = start;
549  framepos_t end = now + nframes;
550  framecnt_t offset = 0;
551 
552  Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
553 
554  if (!lm.locked()) {
555  connect_and_run (bufs, nframes, offset, false);
556  return;
557  }
558 
559  if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
560 
561  /* no events have a time within the relevant range */
562 
563  connect_and_run (bufs, nframes, offset, true, now);
564  return;
565  }
566 
567  while (nframes) {
568 
569  framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
570 
571  connect_and_run (bufs, cnt, offset, true, now);
572 
573  nframes -= cnt;
574  offset += cnt;
575  now += cnt;
576 
577  if (!find_next_event (now, end, next_event)) {
578  break;
579  }
580  }
581 
582  /* cleanup anything that is left to do */
583 
584  if (nframes) {
585  connect_and_run (bufs, nframes, offset, true, now);
586  }
587 }
588 
589 float
591 {
592  if (param.type() != PluginAutomation)
593  return 1.0;
594 
595  if (_plugins.empty()) {
596  fatal << _("programming error: ") << X_("PluginInsert::default_parameter_value() called with no plugin")
597  << endmsg;
598  abort(); /*NOTREACHED*/
599  }
600 
601  return _plugins[0]->default_value (param.id());
602 }
603 
604 
605 bool
607 {
608  bool all = true;
609  uint32_t params = 0;
610  for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
611  bool ok=false;
612  const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
613 
614  if (!ok || !_plugins[0]->parameter_is_input(cid)) {
615  continue;
616  }
617 
619  if (!ac) {
620  continue;
621  }
622 
623  ++params;
624  if (ac->automation_state() & Play) {
625  all = false;
626  break;
627  }
628  }
629  return all && (params > 0);
630 }
631 
632 bool
634 {
635  bool all = true;
636 
637  for (uint32_t par = 0; par < _plugins[0]->parameter_count(); ++par) {
638  bool ok=false;
639  const uint32_t cid = _plugins[0]->nth_parameter (par, ok);
640 
641  if (!ok || !_plugins[0]->parameter_is_input(cid)) {
642  continue;
643  }
644 
645  const float dflt = _plugins[0]->default_value (cid);
646  const float curr = _plugins[0]->get_parameter (cid);
647 
648  if (dflt == curr) {
649  continue;
650  }
651 
653  if (!ac) {
654  continue;
655  }
656 
657  if (ac->automation_state() & Play) {
658  all = false;
659  continue;
660  }
661 
662  ac->set_value (dflt);
663  }
664  return all;
665 }
666 
669 {
671 #ifdef LV2_SUPPORT
673 #endif
674 #ifdef WINDOWS_VST_SUPPORT
676 #endif
677 #ifdef LXVST_SUPPORT
679 #endif
680 #ifdef AUDIOUNIT_SUPPORT
682 #endif
683 
684  if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
685  return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
686 #ifdef LV2_SUPPORT
687  } else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
688  return boost::shared_ptr<Plugin> (new LV2Plugin (*lv2p));
689 #endif
690 #ifdef WINDOWS_VST_SUPPORT
691  } else if ((vp = boost::dynamic_pointer_cast<WindowsVSTPlugin> (other)) != 0) {
692  return boost::shared_ptr<Plugin> (new WindowsVSTPlugin (*vp));
693 #endif
694 #ifdef LXVST_SUPPORT
695  } else if ((lxvp = boost::dynamic_pointer_cast<LXVSTPlugin> (other)) != 0) {
696  return boost::shared_ptr<Plugin> (new LXVSTPlugin (*lxvp));
697 #endif
698 #ifdef AUDIOUNIT_SUPPORT
699  } else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
700  return boost::shared_ptr<Plugin> (new AUPlugin (*ap));
701 #endif
702  }
703 
704  fatal << string_compose (_("programming error: %1"),
705  X_("unknown plugin type in PluginInsert::plugin_factory"))
706  << endmsg;
707  abort(); /*NOTREACHED*/
708  return boost::shared_ptr<Plugin> ((Plugin*) 0);
709 }
710 
711 bool
713 {
714  Match old_match = _match;
715  ChanCount old_in = input_streams ();
716  ChanCount old_out = output_streams ();
717 
718  /* set the matching method and number of plugins that we will use to meet this configuration */
720  if (set_count (_match.plugins) == false) {
721  return false;
722  }
723 
724  if ( (old_match.method != _match.method && (old_match.method == Split || _match.method == Split))
725  || old_in != in
726  || old_out != out
727  )
728  {
729  PluginIoReConfigure (); /* EMIT SIGNAL */
730  }
731 
732  /* configure plugins */
733  switch (_match.method) {
734  case Split:
735  case Hide:
736  if (_plugins.front()->configure_io (_plugins.front()->get_info()->n_inputs, out)) {
737  return false;
738  }
739  break;
740 
741  default:
742  if (_plugins.front()->configure_io (in, out) == false) {
743  return false;
744  }
745  break;
746  }
747 
748  // we don't know the analysis window size, so we must work with the
749  // current buffer size here. each request for data fills in these
750  // buffers and the analyser makes sure it gets enough data for the
751  // analysis window
753  //_signal_analysis_inputs.set_count (in);
754 
756  //_signal_analysis_outputs.set_count (out);
757 
758  // std::cerr << "set counts to i" << in.n_audio() << "/o" << out.n_audio() << std::endl;
759 
760  return Processor::configure_io (in, out);
761 }
762 
771 bool
773 {
775 }
776 
783 {
784  if (_plugins.empty()) {
785  return Match();
786  }
787 
788  PluginInfoPtr info = _plugins.front()->get_info();
789  ChanCount in; in += inx;
790  midi_bypass.reset();
791 
792  if (info->reconfigurable_io()) {
793  /* Plugin has flexible I/O, so delegate to it */
794  bool const r = _plugins.front()->can_support_io_configuration (in, out);
795  if (!r) {
796  return Match (Impossible, 0);
797  }
798 
799  return Match (Delegate, 1);
800  }
801 
802  ChanCount inputs = info->n_inputs;
803  ChanCount outputs = info->n_outputs;
804 
805  if (in.get(DataType::MIDI) == 1 && outputs.get(DataType::MIDI) == 0) {
806  DEBUG_TRACE ( DEBUG::Processors, string_compose ("bypassing midi-data around %1\n", name()));
808  }
809  if (in.get(DataType::MIDI) == 1 && inputs.get(DataType::MIDI) == 0) {
810  DEBUG_TRACE ( DEBUG::Processors, string_compose ("hiding midi-port from plugin %1\n", name()));
811  in.set(DataType::MIDI, 0);
812  }
813 
814  bool no_inputs = true;
815  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
816  if (inputs.get (*t) != 0) {
817  no_inputs = false;
818  break;
819  }
820  }
821 
822  if (no_inputs) {
823  /* no inputs so we can take any input configuration since we throw it away */
824  out = outputs + midi_bypass;
825  return Match (NoInputs, 1);
826  }
827 
828  /* Plugin inputs match requested inputs exactly */
829  if (inputs == in) {
830  out = outputs + midi_bypass;
831  return Match (ExactMatch, 1);
832  }
833 
834  /* We may be able to run more than one copy of the plugin within this insert
835  to cope with the insert having more inputs than the plugin.
836  We allow replication only for plugins with either zero or 1 inputs and outputs
837  for every valid data type.
838  */
839 
840  uint32_t f = 0;
841  bool can_replicate = true;
842  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
843 
844  uint32_t nin = inputs.get (*t);
845 
846  // No inputs of this type
847  if (nin == 0 && in.get(*t) == 0) {
848  continue;
849  }
850 
851  if (nin != 1 || outputs.get (*t) != 1) {
852  can_replicate = false;
853  break;
854  }
855 
856  // Potential factor not set yet
857  if (f == 0) {
858  f = in.get(*t) / nin;
859  }
860 
861  // Factor for this type does not match another type, can not replicate
862  if (f != (in.get(*t) / nin)) {
863  can_replicate = false;
864  break;
865  }
866  }
867 
868  if (can_replicate) {
869  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
870  out.set (*t, outputs.get(*t) * f);
871  }
872  out += midi_bypass;
873  return Match (Replicate, f);
874  }
875 
876  /* If the processor has exactly one input of a given type, and
877  the plugin has more, we can feed the single processor input
878  to some or all of the plugin inputs. This is rather
879  special-case-y, but the 1-to-many case is by far the
880  simplest. How do I split thy 2 processor inputs to 3
881  plugin inputs? Let me count the ways ...
882  */
883 
884  bool can_split = true;
885  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
886 
887  bool const can_split_type = (in.get (*t) == 1 && inputs.get (*t) > 1);
888  bool const nothing_to_do_for_type = (in.get (*t) == 0 && inputs.get (*t) == 0);
889 
890  if (!can_split_type && !nothing_to_do_for_type) {
891  can_split = false;
892  }
893  }
894 
895  if (can_split) {
896  out = outputs + midi_bypass;
897  return Match (Split, 1);
898  }
899 
900  /* If the plugin has more inputs than we want, we can `hide' some of them
901  by feeding them silence.
902  */
903 
904  bool could_hide = false;
905  bool cannot_hide = false;
906  ChanCount hide_channels;
907 
908  for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
909  if (inputs.get(*t) > in.get(*t)) {
910  /* there is potential to hide, since the plugin has more inputs of type t than the insert */
911  hide_channels.set (*t, inputs.get(*t) - in.get(*t));
912  could_hide = true;
913  } else if (inputs.get(*t) < in.get(*t)) {
914  /* we definitely cannot hide, since the plugin has fewer inputs of type t than the insert */
915  cannot_hide = true;
916  }
917  }
918 
919  if (could_hide && !cannot_hide) {
920  out = outputs + midi_bypass;
921  return Match (Hide, 1, hide_channels);
922  }
923 
924  midi_bypass.reset();
925  return Match (Impossible, 0);
926 }
927 
928 XMLNode&
930 {
931  return state (true);
932 }
933 
934 XMLNode&
936 {
937  XMLNode& node = Processor::state (full);
938 
939  node.add_property("type", _plugins[0]->state_node_name());
940  node.add_property("unique-id", _plugins[0]->unique_id());
941  node.add_property("count", string_compose("%1", _plugins.size()));
942  node.add_child_nocopy (_plugins[0]->get_state());
943 
944  for (Controls::iterator c = controls().begin(); c != controls().end(); ++c) {
946  if (ac) {
947  node.add_child_nocopy (ac->get_state());
948  }
949  }
950 
951  return node;
952 }
953 
954 void
955 PluginInsert::set_control_ids (const XMLNode& node, int version)
956 {
957  const XMLNodeList& nlist = node.children();
959  set<Evoral::Parameter>::const_iterator p;
960 
961  for (iter = nlist.begin(); iter != nlist.end(); ++iter) {
962  if ((*iter)->name() == Controllable::xml_node_name) {
963  const XMLProperty* prop;
964 
965  if ((prop = (*iter)->property (X_("parameter"))) != 0) {
966  uint32_t p = atoi (prop->value());
967 
968  /* this may create the new controllable */
969 
971 
972 #ifndef NO_PLUGIN_STATE
973  if (!c) {
974  continue;
975  }
977  if (ac) {
978  ac->set_state (**iter, version);
979  }
980 #endif
981  }
982  }
983  }
984 }
985 
986 int
987 PluginInsert::set_state(const XMLNode& node, int version)
988 {
989  XMLNodeList nlist = node.children();
990  XMLNodeIterator niter;
991  XMLPropertyList plist;
992  const XMLProperty *prop;
994 
995  if ((prop = node.property ("type")) == 0) {
996  error << _("XML node describing plugin is missing the `type' field") << endmsg;
997  return -1;
998  }
999 
1000  if (prop->value() == X_("ladspa") || prop->value() == X_("Ladspa")) { /* handle old school sessions */
1001  type = ARDOUR::LADSPA;
1002  } else if (prop->value() == X_("lv2")) {
1003  type = ARDOUR::LV2;
1004  } else if (prop->value() == X_("windows-vst")) {
1005  type = ARDOUR::Windows_VST;
1006  } else if (prop->value() == X_("lxvst")) {
1007  type = ARDOUR::LXVST;
1008  } else if (prop->value() == X_("audiounit")) {
1009  type = ARDOUR::AudioUnit;
1010  } else {
1011  error << string_compose (_("unknown plugin type %1 in plugin insert state"),
1012  prop->value())
1013  << endmsg;
1014  return -1;
1015  }
1016 
1017  prop = node.property ("unique-id");
1018 
1019  if (prop == 0) {
1020 #ifdef WINDOWS_VST_SUPPORT
1021  /* older sessions contain VST plugins with only an "id" field.
1022  */
1023 
1024  if (type == ARDOUR::Windows_VST) {
1025  prop = node.property ("id");
1026  }
1027 #endif
1028 
1029 #ifdef LXVST_SUPPORT
1030  /*There shouldn't be any older sessions with linuxVST support.. but anyway..*/
1031 
1032  if (type == ARDOUR::LXVST) {
1033  prop = node.property ("id");
1034  }
1035 #endif
1036  /* recheck */
1037 
1038  if (prop == 0) {
1039  error << _("Plugin has no unique ID field") << endmsg;
1040  return -1;
1041  }
1042  }
1043 
1045 
1046  /* treat linux and windows VST plugins equivalent if they have the same uniqueID
1047  * allow to move sessions windows <> linux */
1048 #ifdef LXVST_SUPPORT
1049  if (plugin == 0 && type == ARDOUR::Windows_VST) {
1050  type = ARDOUR::LXVST;
1051  plugin = find_plugin (_session, prop->value(), type);
1052  }
1053 #endif
1054 
1055 #ifdef WINDOWS_VST_SUPPORT
1056  if (plugin == 0 && type == ARDOUR::LXVST) {
1057  type = ARDOUR::Windows_VST;
1058  plugin = find_plugin (_session, prop->value(), type);
1059  }
1060 #endif
1061 
1062  if (plugin == 0) {
1063  error << string_compose(
1064  _("Found a reference to a plugin (\"%1\") that is unknown.\n"
1065  "Perhaps it was removed or moved since it was last used."),
1066  prop->value())
1067  << endmsg;
1068  return -1;
1069  }
1070 
1071  // The name of the PluginInsert comes from the plugin, nothing else
1072  _name = plugin->get_info()->name;
1073 
1074  uint32_t count = 1;
1075 
1076  // Processor::set_state() will set this, but too late
1077  // for it to be available when setting up plugin
1078  // state. We can't call Processor::set_state() until
1079  // the plugins themselves are created and added.
1080 
1081  set_id (node);
1082 
1083  if (_plugins.empty()) {
1084  /* if we are adding the first plugin, we will need to set
1085  up automatable controls.
1086  */
1087  add_plugin (plugin);
1089  set_control_ids (node, version);
1090  }
1091 
1092  if ((prop = node.property ("count")) != 0) {
1093  sscanf (prop->value().c_str(), "%u", &count);
1094  }
1095 
1096  if (_plugins.size() != count) {
1097  for (uint32_t n = 1; n < count; ++n) {
1098  add_plugin (plugin_factory (plugin));
1099  }
1100  }
1101 
1102  Processor::set_state (node, version);
1103 
1104  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1105 
1106  /* find the node with the type-specific node name ("lv2", "ladspa", etc)
1107  and set all plugins to the same state.
1108  */
1109 
1110  if ((*niter)->name() == plugin->state_node_name()) {
1111 
1112  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1113  (*i)->set_state (**niter, version);
1114  }
1115 
1116  break;
1117  }
1118  }
1119 
1120  if (version < 3000) {
1121 
1122  /* Only 2.X sessions need a call to set_parameter_state() - in 3.X and above
1123  this is all handled by Automatable
1124  */
1125 
1126  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1127  if ((*niter)->name() == "Redirect") {
1128  /* XXX do we need to tackle placement? i think not (pd; oct 16 2009) */
1129  Processor::set_state (**niter, version);
1130  break;
1131  }
1132  }
1133 
1134  set_parameter_state_2X (node, version);
1135  }
1136 
1137  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1138  if (active()) {
1139  (*i)->activate ();
1140  } else {
1141  (*i)->deactivate ();
1142  }
1143  }
1144 
1145  return 0;
1146 }
1147 
1148 void
1150 {
1151  XMLNodeList nlist = node.children();
1152  XMLNodeIterator niter;
1153 
1154  /* look for port automation node */
1155 
1156  for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1157 
1158  if ((*niter)->name() != port_automation_node_name) {
1159  continue;
1160  }
1161 
1162  XMLNodeList cnodes;
1163  XMLProperty *cprop;
1164  XMLNodeConstIterator iter;
1165  XMLNode *child;
1166  const char *port;
1167  uint32_t port_id;
1168 
1169  cnodes = (*niter)->children ("port");
1170 
1171  for (iter = cnodes.begin(); iter != cnodes.end(); ++iter){
1172 
1173  child = *iter;
1174 
1175  if ((cprop = child->property("number")) != 0) {
1176  port = cprop->value().c_str();
1177  } else {
1178  warning << _("PluginInsert: Auto: no ladspa port number") << endmsg;
1179  continue;
1180  }
1181 
1182  sscanf (port, "%" PRIu32, &port_id);
1183 
1184  if (port_id >= _plugins[0]->parameter_count()) {
1185  warning << _("PluginInsert: Auto: port id out of range") << endmsg;
1186  continue;
1187  }
1188 
1190  control(Evoral::Parameter(PluginAutomation, 0, port_id), true));
1191 
1192  if (c) {
1193  if (!child->children().empty()) {
1194  c->alist()->set_state (*child->children().front(), version);
1195 
1196  /* In some cases 2.X saves lists with min_yval and max_yval
1197  being FLT_MIN and FLT_MAX respectively. This causes problems
1198  in A3 because these min/max values are used to compute
1199  where GUI control points should be drawn. If we see such
1200  values, `correct' them to the min/max of the appropriate
1201  parameter.
1202  */
1203 
1204  float min_y = c->alist()->get_min_y ();
1205  float max_y = c->alist()->get_max_y ();
1206 
1207  ParameterDescriptor desc;
1208  _plugins.front()->get_parameter_descriptor (port_id, desc);
1209 
1210  if (min_y == FLT_MIN) {
1211  min_y = desc.lower;
1212  }
1213 
1214  if (max_y == FLT_MAX) {
1215  max_y = desc.upper;
1216  }
1217 
1218  c->alist()->set_yrange (min_y, max_y);
1219  }
1220  } else {
1221  error << string_compose (_("PluginInsert: automatable control %1 not found - ignored"), port_id) << endmsg;
1222  }
1223  }
1224 
1225  /* done */
1226 
1227  break;
1228  }
1229 }
1230 
1231 
1232 string
1234 {
1235  if (param.type() == PluginAutomation) {
1236  return _plugins[0]->describe_parameter (param);
1237  } else if (param.type() == PluginPropertyAutomation) {
1239  if (c && !c->desc().label.empty()) {
1240  return c->desc().label;
1241  }
1242  }
1243  return Automatable::describe_parameter(param);
1244 }
1245 
1248 {
1249  if (_user_latency) {
1250  return _user_latency;
1251  }
1252 
1253  return _plugins[0]->signal_latency ();
1254 }
1255 
1258 {
1259  return plugin()->get_info()->type;
1260 }
1261 
1263  const Evoral::Parameter& param,
1264  const ParameterDescriptor& desc,
1266  : AutomationControl (p->session(), param, desc, list, p->describe_parameter(param))
1267  , _plugin (p)
1268 {
1269  if (alist()) {
1270  alist()->reset_default (desc.normal);
1271  if (desc.toggled) {
1273  }
1274  }
1275 
1276  if (desc.toggled) {
1278  }
1279 }
1280 
1282 void
1284 {
1285  /* FIXME: probably should be taking out some lock here.. */
1286 
1287  for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1288  (*i)->set_parameter (_list->parameter().id(), user_val);
1289  }
1290 
1291  boost::shared_ptr<Plugin> iasp = _plugin->_impulseAnalysisPlugin.lock();
1292  if (iasp) {
1293  iasp->set_parameter (_list->parameter().id(), user_val);
1294  }
1295 
1296  AutomationControl::set_value (user_val);
1297 }
1298 
1299 double
1301 {
1303 
1304  if (_desc.logarithmic) {
1305  if (val > 0) {
1306  val = pow (val, 1/1.5);
1307  } else {
1308  val = 0;
1309  }
1310  }
1311 
1312  return val;
1313 }
1314 
1315 double
1317 {
1318  if (_desc.logarithmic) {
1319  if (val <= 0) {
1320  val = 0;
1321  } else {
1322  val = pow (val, 1.5);
1323  }
1324  }
1325 
1327 
1328  return val;
1329 }
1330 
1331 XMLNode&
1333 {
1334  stringstream ss;
1335 
1337  ss << parameter().id();
1338  node.add_property (X_("parameter"), ss.str());
1339 
1340  return node;
1341 }
1342 
1344 double
1346 {
1347  /* FIXME: probably should be taking out some lock here.. */
1348  return _plugin->get_parameter (_list->parameter());
1349 }
1350 
1352  const Evoral::Parameter& param,
1353  const ParameterDescriptor& desc,
1355  : AutomationControl (p->session(), param, desc, list)
1356  , _plugin (p)
1357 {
1358  if (alist()) {
1359  alist()->set_yrange (desc.lower, desc.upper);
1360  alist()->reset_default (desc.normal);
1361  }
1362 
1363  if (desc.toggled) {
1365  }
1366 }
1367 
1368 void
1370 {
1371  /* Old numeric set_value(), coerce to appropriate datatype if possible.
1372  This is lossy, but better than nothing until Ardour's automation system
1373  can handle various datatypes all the way down. */
1374  const Variant value(_desc.datatype, user_val);
1375  if (value.type() == Variant::NOTHING) {
1376  error << "set_value(double) called for non-numeric property" << endmsg;
1377  return;
1378  }
1379 
1380  for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
1381  (*i)->set_property(_list->parameter().id(), value);
1382  }
1383 
1384  _value = value;
1385  AutomationControl::set_value(user_val);
1386 }
1387 
1388 XMLNode&
1390 {
1391  stringstream ss;
1392 
1394  ss << parameter().id();
1395  node.add_property (X_("property"), ss.str());
1396  node.remove_property (X_("value"));
1397 
1398  return node;
1399 }
1400 
1401 double
1403 {
1404  return _value.to_double();
1405 }
1406 
1409 {
1411  if (_impulseAnalysisPlugin.expired()) {
1412  ret = plugin_factory(_plugins[0]);
1413  _impulseAnalysisPlugin = ret;
1414  } else {
1415  ret = _impulseAnalysisPlugin.lock();
1416  }
1417 
1418  return ret;
1419 }
1420 
1421 void
1423 {
1424  // called from outside the audio thread, so this should be safe
1425  // only do audio as analysis is (currently) only for audio plugins
1428 
1431 }
1432 
1434 void
1436 {
1437  plugin->set_insert_id (this->id());
1438 
1439  if (_plugins.empty()) {
1440  /* first (and probably only) plugin instance - connect to relevant signals
1441  */
1442 
1443  plugin->ParameterChanged.connect_same_thread (*this, boost::bind (&PluginInsert::parameter_changed, this, _1, _2));
1444  plugin->StartTouch.connect_same_thread (*this, boost::bind (&PluginInsert::start_touch, this, _1));
1445  plugin->EndTouch.connect_same_thread (*this, boost::bind (&PluginInsert::end_touch, this, _1));
1446  }
1447 
1448  _plugins.push_back (plugin);
1449 }
1450 
1451 void
1453 {
1454  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1455  (*i)->realtime_handle_transport_stopped ();
1456  }
1457 }
1458 
1459 void
1461 {
1462  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1463  (*i)->realtime_locate ();
1464  }
1465 }
1466 
1467 void
1469 {
1470  for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
1471  (*i)->monitoring_changed ();
1472  }
1473 }
1474 
1475 void
1476 PluginInsert::start_touch (uint32_t param_id)
1477 {
1479  if (ac) {
1480  ac->start_touch (session().audible_frame());
1481  }
1482 }
1483 
1484 void
1485 PluginInsert::end_touch (uint32_t param_id)
1486 {
1488  if (ac) {
1489  ac->stop_touch (true, session().audible_frame());
1490  }
1491 }
bool transport_rolling() const
Definition: session.h:592
AutoState automation_state() const
XMLNodeList::iterator XMLNodeIterator
Definition: xml++.h:48
ARDOUR::Session & _session
LIBPBD_API Transmitter fatal
framecnt_t _signal_analysis_collected_nframes
void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
Definition: buffer_set.cc:149
int atoi(const string &s)
Definition: convert.cc:140
ChanCount hide
number of channels to hide
void end_touch(uint32_t param_id)
float lower
Minimum value (in Hz, for frequencies)
ChanCount natural_output_streams() const
we copy one of our insert's inputs to multiple plugin inputs
const std::string & value() const
Definition: xml++.h:159
void set_yrange(double min, double max)
PBD::Signal0< void > PluginIoReConfigure
XMLNode & get_state()
ConnectionList _list
Definition: signals.h:179
void silence(framecnt_t nframes)
BufferSet _signal_analysis_inputs
MatchingMethod method
method to employ
Session & session() const
virtual void set_parameter(uint32_t which, float val)
Definition: plugin.cc:361
void set_count(const ChanCount &count)
Definition: buffer_set.h:93
void create_automatable_parameters()
we `hide' some of the plugin's inputs by feeding them silence
double interface_to_internal(double) const
void collect_signal_for_analysis(framecnt_t nframes)
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
int set_state(const XMLNode &, int version)
PBD::Signal1< void, uint32_t > EndTouch
Definition: plugin.h:270
int set_state(const XMLNode &, int version)
PluginPropertyControl(PluginInsert *p, const Evoral::Parameter &param, const ParameterDescriptor &desc, boost::shared_ptr< AutomationList > list=boost::shared_ptr< AutomationList >())
std::list< XMLProperty * > XMLPropertyList
Definition: xml++.h:50
framecnt_t signal_latency() const
boost::shared_ptr< Control > control(const Parameter &id, bool create_if_missing=false)
Definition: ControlSet.cpp:73
void set_parameter(Evoral::Parameter param, float val)
void ensure_buffer_set(BufferSet &buffers, const ChanCount &howmany)
Definition: session.cc:4353
bool find_next_event(double start, double end, ControlEvent &ev) const
Definition: ControlSet.cpp:91
void set_interpolation(InterpolationStyle)
uint32_t pframes_t
Definition: types.h:61
uint32_t n_audio() const
Definition: chan_count.h:63
tuple f
Definition: signals.py:35
double get_min_y() const
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
our insert's inputs are the same as the plugin's
XMLNode & state(bool)
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
boost::shared_ptr< Plugin > plugin(uint32_t num=0) const
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
virtual bool reconfigurable_io() const
Definition: plugin.h:82
PBD::Signal2< void, uint32_t, float > ParameterChanged
Definition: plugin.h:214
int set_state(const XMLNode &, int version)
Definition: processor.cc:173
AudioBuffer & get_audio(size_t i)
Definition: buffer_set.h:100
we are delegating to the plugin, and it can handle it
void realtime_handle_transport_stopped()
uint32_t n_midi() const
Definition: chan_count.h:66
virtual void add_control(boost::shared_ptr< Evoral::Control >)
Definition: automatable.cc:138
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
void automation_run(BufferSet &bufs, framepos_t start, pframes_t nframes)
Match private_can_support_io_configuration(ChanCount const &, ChanCount &)
#define _(Text)
Definition: i18n.h:11
virtual void deactivate()
Definition: processor.h:80
ChanCount natural_input_streams() const
ChanCount n_outputs
Definition: plugin.h:64
bool reset_parameters_to_default()
static iterator end()
Definition: data_type.h:109
bool can_support_io_configuration(const ChanCount &in, ChanCount &out)
void parameter_changed(uint32_t, float)
float get_parameter(Evoral::Parameter param)
framecnt_t _signal_analysis_collect_nframes_max
#define X_(Text)
Definition: i18n.h:13
static const std::string port_automation_node_name
Definition: plugin_insert.h:51
static const std::string state_node_name
Definition: processor.h:49
int64_t framecnt_t
Definition: types.h:76
ChanCount output_streams() const
XMLProperty * property(const char *)
Definition: xml++.cc:413
Glib::Threads::Mutex & control_lock() const
Definition: ControlSet.hpp:70
float upper
Maximum value (in Hz, for frequencies)
void silence(framecnt_t len, framecnt_t offset=0)
Definition: audio_buffer.cc:83
const ParameterDescriptor & desc() const
virtual double internal_to_interface(double i) const
Definition: controllable.h:71
virtual std::string describe_parameter(Evoral::Parameter param)
Definition: automatable.cc:160
bool configure_io(ChanCount in, ChanCount out)
PluginControl(PluginInsert *p, const Evoral::Parameter &param, const ParameterDescriptor &desc, boost::shared_ptr< AutomationList > list=boost::shared_ptr< AutomationList >())
void can_automate(Evoral::Parameter)
Definition: automatable.cc:188
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
ChanCount input_streams() const
bool set_id(const XMLNode &)
Definition: stateful.cc:381
void set_parameter_state_2X(const XMLNode &node, int version)
void offset_to(DataType t, int32_t delta)
Definition: chan_mapping.cc:87
int set_state(const XMLNode &, int version)
void run(BufferSet &in, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
framecnt_t _user_latency
Definition: latent.h:47
virtual bool configure_io(ChanCount in, ChanCount out)
Definition: processor.cc:246
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
static ChanCount max(const ChanCount &a, const ChanCount &b)
Definition: chan_count.h:138
int64_t framepos_t
Definition: types.h:66
static EventTypeMap & instance()
void connect_and_run(BufferSet &bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now=0)
int set_block_size(pframes_t nframes)
PBD::Property< std::string > _name
double get_max_y() const
LIBPBD_API Transmitter info
PluginInfoPtr get_info() const
Definition: plugin.h:225
bool is_midi_instrument() const
void set_audio(uint32_t a)
Definition: chan_count.h:64
LIBARDOUR_API uint64_t Processors
Definition: debug.cc:35
static const std::string xml_node_name
Definition: controllable.h:116
virtual void activate()=0
ChanCount n_inputs
Definition: plugin.h:63
XMLProperty * add_property(const char *name, const std::string &value)
PBD::Signal2< void, BufferSet *, BufferSet * > AnalysisDataGathered
we have multiple instances of the plugin
const char * name
std::string to_symbol(const Evoral::Parameter &param) const
void reset_default(double val)
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
uint32_t get(DataType t) const
Definition: chan_count.h:59
uint32_t id() const
Definition: Parameter.hpp:49
boost::shared_ptr< Plugin > plugin_factory(boost::shared_ptr< Plugin >)
void set_midi(uint32_t m)
Definition: chan_count.h:67
bool toggled
True iff parameter is boolean.
Type type() const
Definition: variant.h:177
virtual void set_insert_id(PBD::ID id)
Definition: plugin.h:102
Definition: xml++.h:95
void control_list_automation_state_changed(Evoral::Parameter, AutoState)
boost::shared_ptr< ControlList > list()
Definition: Control.hpp:66
std::string name() const
const ChanCount & count() const
Definition: buffer_set.h:87
void remove_property(const std::string &)
Definition: xml++.cc:476
Controls & controls()
Definition: ControlSet.hpp:58
PluginPtr find_plugin(ARDOUR::Session &, std::string unique_id, ARDOUR::PluginType)
void set(DataType t, uint32_t count)
Definition: chan_count.h:58
virtual double interface_to_internal(double i) const
Definition: controllable.h:72
uint32_t type() const
Definition: Parameter.hpp:47
Definition: debug.h:30
PBD::Signal1< void, uint32_t > StartTouch
Definition: plugin.h:269
bool has_no_audio_inputs() const
bool bounce_processing() const
Definition: session.h:872
void set_flags(Flag f)
XMLNode & get_state(void)
virtual XMLNode & state(bool full)
Definition: processor.cc:109
boost::shared_ptr< AutomationControl > automation_control(const Evoral::Parameter &id, bool create_if_missing=false)
Definition: automatable.cc:475
double internal_to_interface(double) const
bool set_count(uint32_t num)
boost::weak_ptr< Plugin > _impulseAnalysisPlugin
virtual void activate()
Definition: processor.h:79
boost::shared_ptr< AutomationList > alist() const
Nothing (void)
Definition: variant.h:40
virtual bool requires_fixed_sized_buffers() const
Definition: processor.h:71
void start_touch(uint32_t param_id)
void add_plugin(boost::shared_ptr< Plugin >)
virtual std::string state_node_name() const =0
bool has_no_inputs() const
float default_parameter_value(const Evoral::Parameter &param)
void read_from(const Sample *src, framecnt_t len, framecnt_t dst_offset=0, framecnt_t src_offset=0)
Definition: audio_buffer.h:39
BufferSet _signal_analysis_outputs
Variant::Type datatype
for properties
static const ChanCount ZERO
Definition: chan_count.h:149
XMLNodeList::const_iterator XMLNodeConstIterator
Definition: xml++.h:49
void set_control_ids(const XMLNode &, int version)
bool active() const
Definition: processor.h:61
plugin has no inputs, so anything goes
BufferSet & get_scratch_buffers(ChanCount count=ChanCount::ZERO, bool silence=true)
Definition: session.cc:4851
static bool type_is_numeric(Type type)
Definition: variant.h:179
uint32_t get(DataType t, uint32_t from, bool *valid)
Definition: chan_mapping.cc:44
std::string name
Definition: plugin.h:59
static iterator begin()
Definition: data_type.h:108
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
void stop_touch(bool mark, double when)
int32_t plugins
number of copies of the plugin that we need
std::string describe_parameter(Evoral::Parameter param)
boost::shared_ptr< Plugin > get_impulse_analysis_plugin()
AutoState
Definition: types.h:145