ardour
vst_plugin.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <glib.h>
21 #include <glib/gstdio.h>
22 
23 #include <glibmm/fileutils.h>
24 #include <glibmm/miscutils.h>
25 
26 #include "pbd/floating.h"
27 #include "pbd/locale_guard.h"
28 
29 #include "ardour/vst_plugin.h"
31 #include "ardour/session.h"
32 #include "ardour/vst_types.h"
34 #include "ardour/audio_buffer.h"
35 
36 #include "i18n.h"
37 
38 using namespace std;
39 using namespace PBD;
40 using namespace ARDOUR;
41 
42 VSTPlugin::VSTPlugin (AudioEngine& engine, Session& session, VSTHandle* handle)
43  : Plugin (engine, session)
44  , _handle (handle)
45  , _state (0)
46  , _plugin (0)
47 {
48 
49 }
50 
52 {
53 
54 }
55 
56 void
58 {
59  _plugin = e;
60  _plugin->user = this;
61 
62  /* set rate and blocksize */
63 
64  _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) _session.frame_rate());
66 }
67 
68 void
70 {
71  _plugin->dispatcher (_plugin, effMainsChanged, 0, 0, NULL, 0.0f);
72 }
73 
74 void
76 {
77  _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f);
78 }
79 
80 int
82 {
83  deactivate ();
84  _plugin->dispatcher (_plugin, effSetBlockSize, 0, nframes, NULL, 0.0f);
85  activate ();
86  return 0;
87 }
88 
89 float
91 {
92  return 0;
93 }
94 
95 float
96 VSTPlugin::get_parameter (uint32_t which) const
97 {
98  return _plugin->getParameter (_plugin, which);
99 }
100 
101 void
102 VSTPlugin::set_parameter (uint32_t which, float newval)
103 {
104  float oldval = get_parameter (which);
105 
106  if (PBD::floateq (oldval, newval, 1)) {
107  return;
108  }
109 
110  _plugin->setParameter (_plugin, which, newval);
111 
112  float curval = get_parameter (which);
113 
114  if (!PBD::floateq (curval, oldval, 1)) {
115  /* value has changed, follow rest of the notification path */
116  Plugin::set_parameter (which, newval);
117  }
118 }
119 
120 uint32_t
121 VSTPlugin::nth_parameter (uint32_t n, bool& ok) const
122 {
123  ok = true;
124  return n;
125 }
126 
131 gchar *
132 VSTPlugin::get_chunk (bool single) const
133 {
134  guchar* data;
135  int32_t data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, single ? 1 : 0, 0, &data, 0);
136  if (data_size == 0) {
137  return 0;
138  }
139 
140  return g_base64_encode (data, data_size);
141 }
142 
148 int
149 VSTPlugin::set_chunk (gchar const * data, bool single)
150 {
151  gsize size = 0;
152  guchar* raw_data = g_base64_decode (data, &size);
153  int const r = _plugin->dispatcher (_plugin, 24 /* effSetChunk */, single ? 1 : 0, size, raw_data, 0);
154  g_free (raw_data);
155  return r;
156 }
157 
158 void
160 {
161  LocaleGuard lg (X_("C"));
162 
163  if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
164 
165  gchar* data = get_chunk (false);
166  if (data == 0) {
167  return;
168  }
169 
170  /* store information */
171 
172  XMLNode* chunk_node = new XMLNode (X_("chunk"));
173 
174  chunk_node->add_content (data);
175  g_free (data);
176 
177  root->add_child_nocopy (*chunk_node);
178 
179  } else {
180 
181  XMLNode* parameters = new XMLNode ("parameters");
182 
183  for (int32_t n = 0; n < _plugin->numParams; ++n) {
184  char index[64];
185  char val[32];
186  snprintf (index, sizeof (index), "param-%d", n);
187  snprintf (val, sizeof (val), "%.12g", _plugin->getParameter (_plugin, n));
188  parameters->add_property (index, val);
189  }
190 
191  root->add_child_nocopy (*parameters);
192  }
193 }
194 
195 int
196 VSTPlugin::set_state (const XMLNode& node, int version)
197 {
198  LocaleGuard lg (X_("C"));
199  int ret = -1;
200 
201  if (node.name() != state_node_name()) {
202  error << _("Bad node sent to VSTPlugin::set_state") << endmsg;
203  return 0;
204  }
205 
206 #ifndef NO_PLUGIN_STATE
207  XMLNode* child;
208 
209  if ((child = find_named_node (node, X_("chunk"))) != 0) {
210 
211  XMLPropertyList::const_iterator i;
212  XMLNodeList::const_iterator n;
213 
214  for (n = child->children ().begin (); n != child->children ().end (); ++n) {
215  if ((*n)->is_content ()) {
216  /* XXX: this may be dubious for the same reasons that we delay
217  execution of load_preset.
218  */
219  ret = set_chunk ((*n)->content().c_str(), false);
220  }
221  }
222 
223  } else if ((child = find_named_node (node, X_("parameters"))) != 0) {
224 
225  XMLPropertyList::const_iterator i;
226 
227  for (i = child->properties().begin(); i != child->properties().end(); ++i) {
228  int32_t param;
229  float val;
230 
231  sscanf ((*i)->name().c_str(), "param-%d", &param);
232  sscanf ((*i)->value().c_str(), "%f", &val);
233 
234  _plugin->setParameter (_plugin, param, val);
235  }
236 
237  ret = 0;
238 
239  }
240 #endif
241 
242  Plugin::set_state (node, version);
243  return ret;
244 }
245 
246 
247 int
249 {
251 
252  memset (&prop, 0, sizeof (VstParameterProperties));
253  desc.min_unbound = false;
254  desc.max_unbound = false;
255  prop.flags = 0;
256 
257  if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) {
258 
259  /* i have yet to find or hear of a VST plugin that uses this */
260  /* RG: faust2vsti does use this :) */
261 
263  desc.lower = prop.minInteger;
264  desc.upper = prop.maxInteger;
265  } else {
266  desc.lower = 0;
267  desc.upper = 1.0;
268  }
269 
270  if (prop.flags & kVstParameterUsesIntStep) {
271 
272  desc.step = prop.stepInteger;
273  desc.smallstep = prop.stepInteger;
274  desc.largestep = prop.stepInteger;
275 
276  } else if (prop.flags & kVstParameterUsesFloatStep) {
277 
278  desc.step = prop.stepFloat;
279  desc.smallstep = prop.smallStepFloat;
280  desc.largestep = prop.largeStepFloat;
281 
282  } else {
283 
284  float range = desc.upper - desc.lower;
285 
286  desc.step = range / 100.0f;
287  desc.smallstep = desc.step / 2.0f;
288  desc.largestep = desc.step * 10.0f;
289  }
290 
291  if (strlen(prop.label) == 0) {
292  _plugin->dispatcher (_plugin, effGetParamName, which, 0, prop.label, 0);
293  }
294 
295  desc.toggled = prop.flags & kVstParameterIsSwitch;
296  desc.logarithmic = false;
297  desc.sr_dependent = false;
298  desc.label = prop.label;
299 
300  } else {
301 
302  /* old style */
303 
304  char label[64];
305  /* some VST plugins expect this buffer to be zero-filled */
306  memset (label, 0, sizeof (label));
307 
308  _plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0);
309 
310  desc.label = label;
311  desc.integer_step = false;
312  desc.lower = 0.0f;
313  desc.upper = 1.0f;
314  desc.step = 0.01f;
315  desc.smallstep = 0.005f;
316  desc.largestep = 0.1f;
317  desc.toggled = false;
318  desc.logarithmic = false;
319  desc.sr_dependent = false;
320  }
321 
322  return 0;
323 }
324 
325 bool
327 {
328  bool s;
329 
330  if (r.user) {
331  s = load_user_preset (r);
332  } else {
333  s = load_plugin_preset (r);
334  }
335 
336  if (s) {
338  }
339 
340  return s;
341 }
342 
343 bool
345 {
346  /* This is a plugin-provided preset.
347  We can't dispatch directly here; too many plugins expects only one GUI thread.
348  */
349 
350  /* Extract the index of this preset from the URI */
351  int id;
352  int index;
353 #ifndef NDEBUG
354  int const p = sscanf (r.uri.c_str(), "VST:%d:%d", &id, &index);
355  assert (p == 2);
356 #else
357  sscanf (r.uri.c_str(), "VST:%d:%d", &id, &index);
358 #endif
359  _state->want_program = index;
360  return true;
361 }
362 
363 bool
365 {
366  /* This is a user preset; we load it, and this code also knows about the
367  non-direct-dispatch thing.
368  */
369 
371  if (t == 0) {
372  return false;
373  }
374 
375  XMLNode* root = t->root ();
376 
377  for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
378  XMLProperty* label = (*i)->property (X_("label"));
379 
380  assert (label);
381 
382  if (label->value() != r.label) {
383  continue;
384  }
385 
386  if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
387 
388  /* Load a user preset chunk from our XML file and send it via a circuitous route to the plugin */
389 
390  if (_state->wanted_chunk) {
391  g_free (_state->wanted_chunk);
392  }
393 
394  for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
395  if ((*j)->is_content ()) {
396  /* we can't dispatch directly here; too many plugins expect only one GUI thread */
397  gsize size = 0;
398  guchar* raw_data = g_base64_decode ((*j)->content().c_str(), &size);
399  _state->wanted_chunk = raw_data;
400  _state->wanted_chunk_size = size;
401  _state->want_chunk = 1;
402  return true;
403  }
404  }
405 
406  return false;
407 
408  } else {
409 
410  for (XMLNodeList::const_iterator j = (*i)->children().begin(); j != (*i)->children().end(); ++j) {
411  if ((*j)->name() == X_("Parameter")) {
412  XMLProperty* index = (*j)->property (X_("index"));
413  XMLProperty* value = (*j)->property (X_("value"));
414 
415  assert (index);
416  assert (value);
417 
418  set_parameter (atoi (index->value().c_str()), atof (value->value().c_str ()));
419  }
420  }
421  return true;
422  }
423  }
424  return false;
425 }
426 
427 string
429 {
431  if (t == 0) {
432  return "";
433  }
434 
435  XMLNode* p = 0;
436  /* XXX: use of _presets.size() + 1 for the unique ID here is dubious at best */
437  string const uri = string_compose (X_("VST:%1:%2"), unique_id (), _presets.size() + 1);
438 
439  if (_plugin->flags & 32 /* effFlagsProgramsChunks */) {
440 
441  p = new XMLNode (X_("ChunkPreset"));
442  p->add_property (X_("uri"), uri);
443  p->add_property (X_("label"), name);
444  gchar* data = get_chunk (true);
445  p->add_content (string (data));
446  g_free (data);
447 
448  } else {
449 
450  p = new XMLNode (X_("Preset"));
451  p->add_property (X_("uri"), uri);
452  p->add_property (X_("label"), name);
453 
454  for (uint32_t i = 0; i < parameter_count(); ++i) {
455  if (parameter_is_input (i)) {
456  XMLNode* c = new XMLNode (X_("Parameter"));
457  c->add_property (X_("index"), string_compose ("%1", i));
458  c->add_property (X_("value"), string_compose ("%1", get_parameter (i)));
459  p->add_child_nocopy (*c);
460  }
461  }
462  }
463 
464  t->root()->add_child_nocopy (*p);
465 
466  std::string f = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
467  f = Glib::build_filename (f, presets_file ());
468 
469  t->write (f);
470  return uri;
471 }
472 
473 void
475 {
477  if (t == 0) {
478  return;
479  }
480 
481  t->root()->remove_nodes_and_delete (X_("label"), name);
482 
483  std::string f = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
484  f = Glib::build_filename (f, presets_file ());
485 
486  t->write (f);
487 }
488 
489 string
491 {
492  char name[64];
493  memset (name, 0, sizeof (name));
494 
495  /* some VST plugins expect this buffer to be zero-filled */
496 
497  _plugin->dispatcher (_plugin, effGetParamName, param.id(), 0, name, 0);
498 
499  if (name[0] == '\0') {
500  strcpy (name, _("Unknown"));
501  }
502 
503  return name;
504 }
505 
508 {
509  if (_user_latency) {
510  return _user_latency;
511  }
512 
513  return *((int32_t *) (((char *) &_plugin->flags) + 12)); /* initialDelay */
514 }
515 
516 set<Evoral::Parameter>
518 {
519  set<Evoral::Parameter> ret;
520 
521  for (uint32_t i = 0; i < parameter_count(); ++i) {
522  ret.insert (ret.end(), Evoral::Parameter(PluginAutomation, 0, i));
523  }
524 
525  return ret;
526 }
527 
528 int
530  ChanMapping in_map, ChanMapping out_map,
531  pframes_t nframes, framecnt_t offset)
532 {
533  Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
534 
535  ChanCount bufs_count;
536  bufs_count.set(DataType::AUDIO, 1);
537  bufs_count.set(DataType::MIDI, 1);
538  _midi_out_buf = 0;
539 
540  BufferSet& silent_bufs = _session.get_silent_buffers(bufs_count);
541  BufferSet& scratch_bufs = _session.get_scratch_buffers(bufs_count);
542 
543  /* VC++ doesn't support the C99 extension that allows
544 
545  typeName foo[variableDefiningSize];
546 
547  Use alloca instead of dynamic array (rather than std::vector which
548  allocs on the heap) because this is realtime code.
549  */
550 
551  float** ins = (float**)alloca(_plugin->numInputs*sizeof(float*));
552  float** outs = (float**)alloca(_plugin->numOutputs*sizeof(float*));
553 
554  int32_t i;
555 
556  uint32_t in_index = 0;
557  for (i = 0; i < (int32_t) _plugin->numInputs; ++i) {
558  uint32_t index;
559  bool valid = false;
560  index = in_map.get(DataType::AUDIO, in_index++, &valid);
561  ins[i] = (valid)
562  ? bufs.get_audio(index).data(offset)
563  : silent_bufs.get_audio(0).data(offset);
564  }
565 
566  uint32_t out_index = 0;
567  for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) {
568  uint32_t index;
569  bool valid = false;
570  index = out_map.get(DataType::AUDIO, out_index++, &valid);
571  outs[i] = (valid)
572  ? bufs.get_audio(index).data(offset)
573  : scratch_bufs.get_audio(0).data(offset);
574  }
575 
576  if (bufs.count().n_midi() > 0) {
577  VstEvents* v = 0;
578  bool valid = false;
579  const uint32_t buf_index_in = in_map.get(DataType::MIDI, 0, &valid);
580  if (valid) {
581  v = bufs.get_vst_midi (buf_index_in);
582  }
583  valid = false;
584  const uint32_t buf_index_out = out_map.get(DataType::MIDI, 0, &valid);
585  if (valid) {
586  _midi_out_buf = &bufs.get_midi(buf_index_out);
587  _midi_out_buf->silence(0, 0);
588  } else {
589  _midi_out_buf = 0;
590  }
591  if (v) {
592  _plugin->dispatcher (_plugin, effProcessEvents, 0, 0, v, 0);
593  }
594  }
595 
596  /* we already know it can support processReplacing */
597  _plugin->processReplacing (_plugin, &ins[0], &outs[0], nframes);
598  _midi_out_buf = 0;
599 
600  return 0;
601 }
602 
603 string
605 {
606  char buf[32];
607 
608  snprintf (buf, sizeof (buf), "%d", _plugin->uniqueID);
609 
610  return string (buf);
611 }
612 
613 
614 const char *
616 {
617  return _handle->name;
618 }
619 
620 const char *
622 {
623  return _info->creator.c_str();
624 }
625 
626 const char *
628 {
629  return _handle->name;
630 }
631 
632 uint32_t
634 {
635  return _plugin->numParams;
636 }
637 
638 bool
640 {
641  return _plugin->flags & effFlagsHasEditor;
642 }
643 
644 void
645 VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t /*len*/) const
646 {
647  char *first_nonws;
648 
649  _plugin->dispatcher (_plugin, 7 /* effGetParamDisplay */, param, 0, buf, 0);
650 
651  if (buf[0] == '\0') {
652  return;
653  }
654 
655  first_nonws = buf;
656  while (*first_nonws && isspace (*first_nonws)) {
657  first_nonws++;
658  }
659 
660  if (*first_nonws == '\0') {
661  return;
662  }
663 
664  memmove (buf, first_nonws, strlen (buf) - (first_nonws - buf) + 1);
665 }
666 
667 void
669 {
670  /* Built-in presets */
671 
672  int const vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, NULL, 0);
673  for (int i = 0; i < _plugin->numPrograms; ++i) {
674  PresetRecord r (string_compose (X_("VST:%1:%2"), unique_id (), i), "", -1, false);
675 
676  if (vst_version >= 2) {
677  char buf[256];
678  if (_plugin->dispatcher (_plugin, 29, i, 0, buf, 0) == 1) {
679  r.label = buf;
680  } else {
681  r.label = string_compose (_("Preset %1"), i);
682  }
683  } else {
684  r.label = string_compose (_("Preset %1"), i);
685  }
686 
687  _presets.insert (make_pair (r.uri, r));
688  }
689 
690  /* User presets from our XML file */
691 
693 
694  if (t) {
695  XMLNode* root = t->root ();
696  for (XMLNodeList::const_iterator i = root->children().begin(); i != root->children().end(); ++i) {
697 
698  XMLProperty* uri = (*i)->property (X_("uri"));
699  XMLProperty* label = (*i)->property (X_("label"));
700 
701  assert (uri);
702  assert (label);
703 
704  PresetRecord r (uri->value(), label->value(), -1, true);
705  _presets.insert (make_pair (r.uri, r));
706  }
707  }
708 
709 }
710 
714 XMLTree *
716 {
717  XMLTree* t = new XMLTree;
718 
719  std::string p = Glib::build_filename (ARDOUR::user_config_directory (), "presets");
720 
721  if (!Glib::file_test (p, Glib::FILE_TEST_IS_DIR)) {
722  if (g_mkdir_with_parents (p.c_str(), 0755) != 0) {
723  error << _("Unable to make VST presets directory") << endmsg;
724  };
725  }
726 
727  p = Glib::build_filename (p, presets_file ());
728 
729  if (!Glib::file_test (p, Glib::FILE_TEST_EXISTS)) {
730  t->set_root (new XMLNode (X_("VSTPresets")));
731  return t;
732  }
733 
734  t->set_filename (p);
735  if (!t->read ()) {
736  delete t;
737  return 0;
738  }
739 
740  return t;
741 }
742 
744 int
746 {
747  return _plugin->numPrograms;
748 }
749 
750 string
752 {
753  return string_compose ("vst-%1", unique_id ());
754 }
755 
float get_parameter(uint32_t port) const
Definition: vst_plugin.cc:96
int atoi(const string &s)
Definition: convert.cc:140
const XMLPropertyList & properties() const
Definition: xml++.h:119
void set_parameter(uint32_t port, float val)
Definition: vst_plugin.cc:102
virtual int set_state(const XMLNode &, int version)
Definition: plugin.cc:369
float lower
Minimum value (in Hz, for frequencies)
MidiBuffer & get_midi(size_t i)
Definition: buffer_set.h:107
const std::string & value() const
Definition: xml++.h:159
int numParams
Definition: aeffectx.h:280
int set_chunk(gchar const *, bool)
Definition: vst_plugin.cc:149
bool write() const
Definition: xml++.cc:147
VSTState * _state
Definition: vst_plugin.h:96
virtual void set_parameter(uint32_t which, float val)
Definition: plugin.cc:361
float default_value(uint32_t port)
Definition: vst_plugin.cc:90
const std::string & name() const
Definition: xml++.h:104
bool load_plugin_preset(PresetRecord)
Definition: vst_plugin.cc:344
float(* getParameter)(struct _AEffect *, int)
Definition: aeffectx.h:276
char label[VestigeMaxLabelLen]
Definition: aeffectx.h:235
void silence(framecnt_t nframes, framecnt_t offset=0)
Definition: midi_buffer.cc:290
bool load_user_preset(PresetRecord)
Definition: vst_plugin.cc:364
bool has_editor() const
Definition: vst_plugin.cc:639
uint32_t pframes_t
Definition: types.h:61
void(* setParameter)(struct _AEffect *, int, float)
Definition: aeffectx.h:274
tuple f
Definition: signals.py:35
intptr_t(* dispatcher)(struct _AEffect *, int, int, intptr_t, void *, float)
Definition: aeffectx.h:270
MidiBuffer * _midi_out_buf
Definition: vst_plugin.h:99
int wanted_chunk_size
Definition: vst_types.h:112
Definition: Beats.hpp:239
PluginInfoPtr _info
Definition: plugin.h:287
LIBPBD_API Transmitter error
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
#define effMainsChanged
Definition: aeffectx.h:97
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
std::string presets_file() const
Definition: vst_plugin.cc:751
framecnt_t signal_latency() const
Definition: vst_plugin.cc:507
#define effGetParameterProperties
Definition: aeffectx.h:114
int want_chunk
Definition: vst_types.h:109
framecnt_t frame_rate() const
Definition: session.h:365
AudioBuffer & get_audio(size_t i)
Definition: buffer_set.h:100
int set_state(XMLNode const &, int)
Definition: vst_plugin.cc:196
static bool floateq(float a, float b, int max_ulps_diff)
Definition: floating.h:52
Definition: xml++.h:55
uint32_t n_midi() const
Definition: chan_count.h:66
int connect_and_run(BufferSet &, ChanMapping in, ChanMapping out, pframes_t nframes, framecnt_t offset)
Definition: vst_plugin.cc:529
virtual int connect_and_run(BufferSet &bufs, ChanMapping in, ChanMapping out, pframes_t nframes, framecnt_t offset)
Definition: plugin.cc:259
virtual ~VSTPlugin()
Definition: vst_plugin.cc:51
#define _(Text)
Definition: i18n.h:11
LIBARDOUR_API std::string user_config_directory(int version=-1)
#define effSetSampleRate
Definition: aeffectx.h:95
#define X_(Text)
Definition: i18n.h:13
const char * name() const
Definition: vst_plugin.cc:615
int64_t framecnt_t
Definition: types.h:76
std::string do_save_preset(std::string name)
Definition: vst_plugin.cc:428
#define effGetParamName
Definition: aeffectx.h:94
float upper
Maximum value (in Hz, for frequencies)
XMLNode * set_root(XMLNode *n)
Definition: xml++.h:63
void print_parameter(uint32_t, char *, uint32_t len) const
Definition: vst_plugin.cc:645
XMLNode * root() const
Definition: xml++.h:62
Definition: amp.h:29
std::map< std::string, PresetRecord > _presets
Definition: plugin.h:289
const PBD::ID & id() const
Definition: stateful.h:68
AEffect * _plugin
Definition: vst_plugin.h:97
int set_block_size(pframes_t)
Definition: vst_plugin.cc:81
void set_plugin(AEffect *)
Definition: vst_plugin.cc:57
framecnt_t _user_latency
Definition: latent.h:47
bool read()
Definition: xml++.h:71
void(* processReplacing)(struct _AEffect *, float **, float **, int)
Definition: aeffectx.h:303
LIBARDOUR_API XMLNode * find_named_node(const XMLNode &node, std::string name)
const char * label() const
Definition: vst_plugin.cc:627
int get_parameter_descriptor(uint32_t which, ParameterDescriptor &) const
Definition: vst_plugin.cc:248
int first_user_preset_index() const
Definition: vst_plugin.cc:745
const std::string & set_filename(const std::string &fn)
Definition: xml++.h:66
#define effGetVstVersion
Definition: aeffectx.h:115
#define effProcessEvents
Definition: aeffectx.h:103
void do_remove_preset(std::string name)
Definition: vst_plugin.cc:474
#define effFlagsHasEditor
Definition: aeffectx.h:85
VSTHandle * _handle
Definition: vst_plugin.h:95
XMLProperty * add_property(const char *name, const std::string &value)
int32_t uniqueID
Definition: aeffectx.h:299
void add_state(XMLNode *) const
Definition: vst_plugin.cc:159
const char * name
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
uint32_t id() const
Definition: Parameter.hpp:49
pframes_t get_block_size() const
Definition: session.h:393
bool toggled
True iff parameter is boolean.
XMLNode * add_content(const std::string &s=std::string())
Definition: xml++.cc:407
uint32_t nth_parameter(uint32_t port, bool &ok) const
Definition: vst_plugin.cc:121
Definition: xml++.h:95
bool parameter_is_input(uint32_t) const
Definition: vst_plugin.h:57
int want_program
Definition: vst_types.h:108
const ChanCount & count() const
Definition: buffer_set.h:87
void set(DataType t, uint32_t count)
Definition: chan_count.h:58
std::string unique_id() const
Definition: vst_plugin.cc:604
ARDOUR::Session & _session
Definition: plugin.h:286
gchar * get_chunk(bool) const
Definition: vst_plugin.cc:132
int numOutputs
Definition: aeffectx.h:284
int numPrograms
Definition: aeffectx.h:278
Definition: debug.h:30
std::string creator
Definition: plugin.h:61
XMLTree * presets_tree() const
Definition: vst_plugin.cc:715
int numInputs
Definition: aeffectx.h:282
int flags
Definition: aeffectx.h:286
std::string describe_parameter(Evoral::Parameter)
Definition: vst_plugin.cc:490
const Sample * data(framecnt_t offset=0) const
Definition: audio_buffer.h:187
uint32_t parameter_count() const
Definition: vst_plugin.cc:633
bool load_preset(PresetRecord)
Definition: vst_plugin.cc:326
virtual std::string state_node_name() const =0
void remove_nodes_and_delete(const std::string &)
unsigned char * wanted_chunk
Definition: vst_types.h:111
BufferSet & get_silent_buffers(ChanCount count=ChanCount::ZERO)
Definition: session.cc:4845
char * name
Definition: vst_types.h:64
virtual bool load_preset(PresetRecord)
Definition: plugin.cc:340
BufferSet & get_scratch_buffers(ChanCount count=ChanCount::ZERO, bool silence=true)
Definition: session.cc:4851
uint32_t get(DataType t, uint32_t from, bool *valid)
Definition: chan_mapping.cc:44
std::set< Evoral::Parameter > automatable() const
Definition: vst_plugin.cc:517
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
#define effSetBlockSize
Definition: aeffectx.h:96
double atof(const string &s)
Definition: convert.cc:158
void * user
Definition: aeffectx.h:297
const char * maker() const
Definition: vst_plugin.cc:621