Guitarix
ladspaplugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Andreas Degert, Hermann Meyer
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <dlfcn.h>
20 #include <ladspa.h>
21 
22 #include "engine.h"
23 
27 using Glib::ustring;
28 
29 namespace gx_engine {
30 
31 /****************************************************************
32  ** class LadspaDsp
33  */
34 
35 class LadspaDsp: public PluginDef {
36 private:
37  static void init(unsigned int samplingFreq, PluginDef *plugin);
38  static void mono_process(int count, float *input, float *output, PluginDef *plugin);
39  static void to_mono_process(int count, float *input, float *output, PluginDef *plugin);
40  static void stereo_process(int count, float *input1, float *input2, float *output1, float *output2, PluginDef *plugin);
41  static int activate(bool start, PluginDef *plugin);
42  static int registerparam(const ParamReg& reg);
43  static int uiloader(const UiBuilder& builder, int form);
44  static void del_instance(PluginDef *plugin);
45  //
46  const LADSPA_Descriptor *desc;
47  void *handle;
48  LADSPA_Handle instance;
49  LADSPA_Data *ports;
50  Glib::ustring name_str;
51  Glib::ustring dest_str;
52  const plugdesc *pd;
53  bool is_activated;
54  void connect(int tp, int i, float *v);
55  inline void cleanup();
56  void set_shortname();
57  float dry_wet;
58  std::string idd;
59  inline void mono_dry_wet(int count, float *input0, float *input1, float *output0);
60  inline void stereo_dry_wet(int count, float *input0, float *input1, float *input2, float *input3, float *output0, float *output1);
61  inline void down_to_mono(int count, float *input0, float *input1, float *output0);
62  inline void up_to_stereo(int count, float *input0, float *output0, float *output1);
63  std::string make_id(const paradesc& p);
64  LadspaDsp(const plugdesc *plug, void *handle_, const LADSPA_Descriptor *desc_, bool mono, bool to_mono);
65  ~LadspaDsp();
66 public:
67  static LadspaDsp *create(const plugdesc *plug);
68  void set_plugdesc(const plugdesc* pd_);
69 };
70 
72  void *handle;
73  handle = dlopen(plug->path.c_str(), RTLD_LOCAL|RTLD_NOW);
74  if (!handle) {
75  gx_print_error("ladspaloader",ustring::compose(_("Cannot open plugin: %1 [%2]"), plug->path, dlerror()));
76  return NULL;
77  }
78  LADSPA_Descriptor_Function ladspa_descriptor = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
79  const char *dlsym_error = dlerror();
80  if (dlsym_error) {
81  gx_print_error("ladspaloader",ustring::compose(_("Cannot load symbol 'ladspa_descriptor': %1"), dlsym_error));
82  dlclose(handle);
83  handle = 0;
84  return NULL;
85  }
86  const LADSPA_Descriptor *desc = ladspa_descriptor(plug->index);
87  if (!desc || desc->UniqueID != plug->UniqueID) {
88  for (int i = 0; ; i++) {
89  desc = ladspa_descriptor(i);
90  if (!desc) {
91  break;
92  }
93  if (desc->UniqueID == plug->UniqueID) {
94  break;
95  }
96  }
97  }
98  if (!desc) {
99  gx_print_error("ladspaloader",ustring::compose(_("Cannot load ladspa descriptor #%1 from %2"), plug->index, plug->path));
100  dlclose(handle);
101  handle = 0;
102  return NULL;
103  }
104  if (desc->UniqueID == 4069 || desc->UniqueID == 4070) {
105  gx_print_error("ladspaloader",_("ladspa_guitarix not loaded"));
106  dlclose(handle);
107  handle = 0;
108  return NULL;
109  }
110  int num_inputs = 0;
111  int num_outputs = 0;
112  for (unsigned int i = 0; i < desc->PortCount; ++i) {
113  if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i])) {
114  if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
115  num_inputs += 1;
116  } else { // LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])
117  num_outputs += 1;
118  }
119  }
120  }
121  bool mono;
122  bool to_mono = false;
123  if (num_inputs == 1 && num_outputs == 1) {
124  mono = true;
125  } else if (num_inputs == 2 && num_outputs == 2) {
126  mono = false;
127  if (plug->stereo_to_mono) to_mono = true;
128  } else {
130  "ladspaloader",ustring::compose(
131  _("cannot use ladspa plugin %1 with %2 inputs and %3 outputs"),
132  desc->Label, num_inputs, num_outputs));
133  dlclose(handle);
134  handle = 0;
135  return NULL;
136  }
137 
138  LadspaDsp* self = new LadspaDsp(plug, handle, desc, mono, to_mono);
139  PluginDef& pl = *static_cast<PluginDef*>(self);
140  pl.flags |=PGNI_IS_LADSPA;
141  return self;
142 }
143 
144 LadspaDsp::LadspaDsp(const plugdesc *plug, void *handle_, const LADSPA_Descriptor *desc_, bool mono, bool to_mono)
145  : PluginDef(), desc(desc_), handle(handle_), instance(),
146  ports(new LADSPA_Data[desc->PortCount]), name_str(), dest_str(), pd(plug), is_activated(false) {
148  id = pd->id_str.c_str();
149  category = pd->category.c_str();
150  dest_str = "LADSPA ";
151  dest_str += desc->Name;
152  dest_str += " by ";
153  dest_str += desc->Maker;
154  description = dest_str.c_str();
155  name = desc->Name;
156  set_shortname();
157  set_samplerate = init;
158  if (mono) {
159  mono_audio = mono_process;
160  } else {
161  if (to_mono) mono_audio = to_mono_process;
162  else stereo_audio = stereo_process;
163  }
164  activate_plugin = activate;
165  register_params = registerparam;
166  load_ui = uiloader;
167  delete_instance = del_instance;
168 }
169 
170 inline void LadspaDsp::cleanup() {
171  if (instance) {
172  if (pd->quirks & need_activate) {
173  activate(true, this);
174  }
175  activate(false, this);
176  if (!(pd->quirks & no_cleanup)) {
177  desc->cleanup(instance);
178  }
179  instance = 0;
180  }
181 }
182 
185  while (jp.peek() != gx_system::JsonParser::end_object) {
187  if (jp.read_kv("index", index) ||
188  jp.read_kv("name", name) ||
189  jp.read_kv("dflt", dflt) ||
190  jp.read_kv("low", low) ||
191  jp.read_kv("up", up) ||
192  jp.read_kv("step", step) ||
193  jp.read_kv("tp", tp) ||
194  jp.read_kv("newrow", newrow) ||
195  jp.read_kv("has_caption", has_caption)) {
196  } else if (jp.current_value() == "values") {
197  std::vector<std::string> v;
199  while (jp.peek() != gx_system::JsonParser::end_array) {
201  v.push_back(jp.current_value());
202  }
204  set_valuelist(v);
205  } else {
206  assert(false);
207  }
208  }
210 }
211 
213  jw.begin_object();
214  jw.write_kv("index", index);
215  jw.write_kv("name", name);
216  jw.write_kv("dflt", dflt);
217  jw.write_kv("low", low);
218  jw.write_kv("up", up);
219  jw.write_kv("step", step);
220  jw.write_kv("tp", tp);
221  jw.write_kv("newrow", newrow);
222  jw.write_kv("has_caption", has_caption);
223  if (values) {
224  jw.write_key("values");
225  jw.begin_array();
226  for (value_pair *p = values; p->value_id; p++) {
227  jw.begin_array();
228  jw.write(p->value_id);
229  jw.write(p->value_label);
230  jw.end_array();
231  }
232  jw.end_array();
233  }
234  jw.end_object();
235 }
236 
239  while (jp.peek() != gx_system::JsonParser::end_object) {
241  if (jp.read_kv("path", path) ||
242  jp.read_kv("index", index) ||
243  jp.read_kv("UniqueID", UniqueID) ||
244  jp.read_kv("Label", Label) ||
245  jp.read_kv("shortname", shortname) ||
246  jp.read_kv("category", category) ||
247  jp.read_kv("quirks", quirks) ||
248  jp.read_kv("add_wet_dry", add_wet_dry) ||
249  jp.read_kv("stereo_to_mono", stereo_to_mono) ||
250  jp.read_kv("master_idx", master_idx) ||
251  jp.read_kv("master_label", master_label) ||
252  jp.read_kv("id_str", id_str)) {
253  } else if (jp.current_value() == "names") {
255  while (jp.peek() != gx_system::JsonParser::end_array) {
256  paradesc *p = new paradesc();
257  p->readJSON(jp);
258  names.push_back(p);
259  }
261  } else {
262  assert(false);
263  }
264  }
266 }
267 
269  jw.begin_object();
270  jw.write_kv("path", path);
271  jw.write_kv("index", index);
272  jw.write_kv("UniqueID", static_cast<unsigned int>(UniqueID));
273  jw.write_kv("Label", Label);
274  jw.write_kv("shortname", shortname);
275  jw.write_kv("category", category);
276  jw.write_kv("quirks", quirks);
277  jw.write_kv("add_wet_dry", add_wet_dry);
278  jw.write_kv("stereo_to_mono", stereo_to_mono);
279  jw.write_kv("master_idx", master_idx);
280  jw.write_kv("master_label", master_label);
281  jw.write_kv("id_str", id_str);
282  jw.write_key("names");
283  jw.begin_array();
284  for (std::vector<paradesc*>::iterator i = names.begin(); i != names.end(); ++i) {
285  (*i)->writeJSON(jw);
286  }
287  jw.end_array();
288  jw.end_object();
289 }
290 
291 plugdesc::~plugdesc() {
292  for (std::vector<paradesc*>::const_iterator it = names.begin(); it != names.end(); ++it) {
293  delete *it;
294  }
295 }
296 
297 LadspaDsp::~LadspaDsp() {
298  cleanup();
299  if (handle && !(pd->quirks & no_cleanup)) {
300  dlclose(handle);
301  }
302  delete[] ports;
303 }
304 
305 int LadspaDsp::activate(bool start, PluginDef *plugin) {
306  LadspaDsp& self = *static_cast<LadspaDsp*>(plugin);
307  if (start == self.is_activated) {
308  return 0;
309  }
310  self.is_activated = start;
311  if (start) {
312  if (self.desc->activate) {
313  self.desc->activate(self.instance);
314  }
315  } else {
316  if (self.desc->deactivate) {
317  self.desc->deactivate(self.instance);
318  }
319  }
320  return 0;
321 }
322 
323 void LadspaDsp::connect(int tp, int i, float *v) {
324  for (unsigned int n = 0; n < desc->PortCount; ++n) {
325  if (!LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[n])) {
326  continue;
327  }
328  if (desc->PortDescriptors[n] & tp) {
329  if (i == 0) {
330  desc->connect_port(instance, n, v);
331  return;
332  }
333  i -= 1;
334  }
335  }
336  gx_print_error("ladspaloader", _("audio port not found"));
337 }
338 
340  pd = pd_;
341  id = pd->id_str.c_str();
342  category = pd->category.c_str();
343  set_shortname();
344 }
345 
346 void LadspaDsp::set_shortname() {
347  if (!pd->shortname.empty()) {
348  shortname = pd->shortname.c_str();
349  } else {
350  name_str = desc->Name;
351  if (name_str.size() > 15) {
352  name_str.erase(15);
353  }
354  shortname = name_str.c_str();
355  }
356 }
357 
358 void LadspaDsp::init(unsigned int samplingFreq, PluginDef *plugin) {
359  LadspaDsp& self = *static_cast<LadspaDsp*>(plugin);
360  self.cleanup();
361  if (samplingFreq == 0) {
362  return;
363  }
364  self.instance = self.desc->instantiate(self.desc, samplingFreq);
365  int n = 0;
366  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
367  self.desc->connect_port(self.instance, (*it)->index, &self.ports[(*it)->index]);
368  }
369 }
370 
371 inline void LadspaDsp::mono_dry_wet(int count, float *input0, float *input1, float *output0)
372 {
373  double fSlow0 = (0.01 * dry_wet);
374  double fSlow1 = (1 - fSlow0);
375  for (int i=0; i<count; i++) {
376  output0[i] = ((fSlow0 * (double)input1[i]) + (fSlow1 * (double)input0[i]));
377  }
378 }
379 
380 void LadspaDsp::mono_process(int count, float *input, float *output, PluginDef *plugin) {
381  LadspaDsp& self = *static_cast<LadspaDsp*>(plugin);
382  assert(self.is_activated);
383  if (self.pd->add_wet_dry) {
384  float wet_out[count];
385  self.connect(LADSPA_PORT_INPUT, 0, input);
386  self.connect(LADSPA_PORT_OUTPUT, 0, wet_out);
387  self.desc->run(self.instance, count);
388  self.mono_dry_wet(count, input, wet_out, output);
389  } else {
390  self.connect(LADSPA_PORT_INPUT, 0, input);
391  self.connect(LADSPA_PORT_OUTPUT, 0, output);
392  self.desc->run(self.instance, count);
393  }
394 }
395 
396 void LadspaDsp::up_to_stereo(int count, float *input0, float *output0, float *output1) {
397  memcpy(output0, input0, count * sizeof(float));
398  memcpy(output1, input0, count * sizeof(float));
399 }
400 
401 void LadspaDsp::down_to_mono(int count, float *input0, float *input1, float *output0) {
402  for (int i=0; i<count; i++) {
403  output0[i] = 0.5 * (input0[i] + input1[i]);
404  }
405 }
406 
407 void LadspaDsp::to_mono_process(int count, float *input, float *output, PluginDef *plugin) {
408  LadspaDsp& self = *static_cast<LadspaDsp*>(plugin);
409  assert(self.is_activated);
410  if (self.pd->add_wet_dry) {
411  float wet_out[count];
412  float inputs[count];
413  float inputs1[count];
414  float outputs[count];
415  float outputs1[count];
416  self.up_to_stereo(count,input,inputs, inputs1);
417  self.connect(LADSPA_PORT_INPUT, 0, inputs);
418  self.connect(LADSPA_PORT_INPUT, 1, inputs1);
419  self.connect(LADSPA_PORT_INPUT, 0, outputs);
420  self.connect(LADSPA_PORT_INPUT, 1, outputs1);
421  self.desc->run(self.instance, count);
422  self.down_to_mono(count,outputs,outputs1,wet_out);
423  self.mono_dry_wet(count, input, wet_out, output);
424  } else {
425  float inputs[count];
426  float inputs1[count];
427  float outputs[count];
428  float outputs1[count];
429  self.up_to_stereo(count,input,inputs, inputs1);
430  self.connect(LADSPA_PORT_INPUT, 0, inputs);
431  self.connect(LADSPA_PORT_INPUT, 1, inputs1);
432  self.connect(LADSPA_PORT_INPUT, 0, outputs);
433  self.connect(LADSPA_PORT_INPUT, 1, outputs1);
434  self.desc->run(self.instance, count);
435  self.down_to_mono(count,outputs,outputs1,output);
436  }
437 }
438 
439 inline void LadspaDsp::stereo_dry_wet(int count, float *input0, float *input1, float *input2, float *input3, float *output0, float *output1)
440 {
441  double fSlow0 = (0.01 * dry_wet);
442  double fSlow1 = (1 - fSlow0);
443  for (int i=0; i<count; i++) {
444  output0[i] = ((fSlow0 * (double)input2[i]) + (fSlow1 * (double)input0[i]));
445  output1[i] = ((fSlow0 * (double)input3[i]) + (fSlow1 * (double)input1[i]));
446  }
447 }
448 
449 void LadspaDsp::stereo_process(int count, float *input1, float *input2, float *output1, float *output2, PluginDef *plugin) {
450  LadspaDsp& self = *static_cast<LadspaDsp*>(plugin);
451  assert(self.is_activated);
452  if (self.pd->add_wet_dry) {
453  float wet_out1[count];
454  float wet_out2[count];
455  self.connect(LADSPA_PORT_INPUT, 0, input1);
456  self.connect(LADSPA_PORT_INPUT, 1, input2);
457  self.connect(LADSPA_PORT_OUTPUT, 0, wet_out1);
458  self.connect(LADSPA_PORT_OUTPUT, 1, wet_out2);
459  self.desc->run(self.instance, count);
460  self.stereo_dry_wet(count, input1, input2, wet_out1, wet_out2, output1, output2);
461  } else {
462  self.connect(LADSPA_PORT_INPUT, 0, input1);
463  self.connect(LADSPA_PORT_INPUT, 1, input2);
464  self.connect(LADSPA_PORT_OUTPUT, 0, output1);
465  self.connect(LADSPA_PORT_OUTPUT, 1, output2);
466  self.desc->run(self.instance, count);
467  }
468 }
469 
470 static Glib::ustring TrimLabel(const char *label, int cnt_in_row) {
471  const size_t minlen = 60 / cnt_in_row - 1;
472  const size_t maxlen = minlen + 10;
473  const size_t cutlen = (maxlen + minlen) / 2;
474  Glib::ustring pn(label);
475  size_t rem = pn.find_first_of("([");
476  if(rem != Glib::ustring::npos) {
477  pn.erase(rem);
478  }
479  while ((rem = pn.find_last_of(" ")) == pn.size()-1) {
480  pn.erase(rem);
481  }
482  rem = 0;
483  size_t rem1 = 0;
484  size_t lastpos = 0;
485  while (true) {
486  rem1 = pn.find_first_of(" ", rem1);
487  if (rem1 == Glib::ustring::npos) {
488  rem1 = pn.size();
489  }
490  while (rem1 > rem + minlen) {
491  if (lastpos > rem) {
492  rem = lastpos;
493  pn.replace(lastpos, 1, 1, '\n');
494  } else if (rem1 < rem + maxlen) {
495  if (rem1 == pn.size()) {
496  break;
497  }
498  rem = rem1;
499  pn.replace(rem1, 1, 1, '\n');
500  } else {
501  rem += cutlen;
502  pn.insert(rem, "\n");
503  }
504  rem += 1;
505  }
506  lastpos = rem1;
507  rem1 += 1;
508  if (rem1 >= pn.size()) {
509  break;
510  }
511  }
512  return pn;
513 }
514 
515 static Glib::ustring TrimEffectLabel(const char *label, int cnt_in_row) {
516  const size_t minlen = 60 / cnt_in_row - 1;
517  const size_t maxlen = minlen + 10;
518  const size_t cutlen = (maxlen + minlen) / 2;
519  Glib::ustring pn(label);
520  size_t rem = 0;
521  size_t rem1 = 0;
522  size_t lastpos = 0;
523  while (true) {
524  rem1 = pn.find_first_of(" ", rem1);
525  if (rem1 == Glib::ustring::npos) {
526  rem1 = pn.size();
527  }
528  while (rem1 > rem + minlen) {
529  if (lastpos > rem) {
530  rem = lastpos;
531  pn.replace(lastpos, 1, 1, '\n');
532  } else if (rem1 < rem + maxlen) {
533  if (rem1 == pn.size()) {
534  break;
535  }
536  rem = rem1;
537  pn.replace(rem1, 1, 1, '\n');
538  } else {
539  rem += cutlen;
540  pn.insert(rem, "\n");
541  }
542  rem += 1;
543  }
544  lastpos = rem1;
545  rem1 += 1;
546  if (rem1 >= pn.size()) {
547  break;
548  }
549  }
550  return pn;
551 }
552 
553 std::string LadspaDsp::make_id(const paradesc& p) {
554  return pd->id_str + "." + to_string(p.index);
555 }
556 
557 int LadspaDsp::registerparam(const ParamReg& reg) {
558  LadspaDsp& self = *static_cast<LadspaDsp*>(reg.plugin);
559  int n = 0;
560  int cnt_in_row = 0;
561  int left = 0;
562  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
563  paradesc *d = *it;
564  if (d->tp != tp_none) {
565  left -= 1;
566  if (left < 0) {
567  cnt_in_row = 1;
568  std::vector<paradesc*>::const_iterator it2 = it+1;
569  while (it2 != self.pd->names.end() && !(*it2)->newrow) {
570  if ((*it2)->tp != tp_none) {
571  ++cnt_in_row;
572  }
573  ++it2;
574  }
575  left = cnt_in_row;
576  }
577  }
578  const char *nm = self.desc->PortNames[d->index];
579  Glib::ustring snm(d->name);
580  if (snm.empty() && d->tp != tp_none) {
581  snm = TrimLabel(nm, cnt_in_row);
582  }
583  if (d->tp == tp_enum) {
584  reg.registerEnumVar(self.make_id(*d).c_str(), snm.c_str(), "S", nm, d->values, &self.ports[d->index],
585  d->dflt, d->low, d->up, d->step);
586  } else {
587  const char *tp = 0;
588  switch (d->tp) {
589  case tp_none: tp = "S"; break;
590  case tp_int: tp = "S"; break;
591  case tp_scale: tp = "S"; break;
592  case tp_scale_log: tp = "SL"; break;
593  case tp_enabled: tp = "B"; break;
594  case tp_toggle: tp = "B"; break;
595  case tp_display: tp = "SO"; break;
596  case tp_display_toggle: tp = "BO"; break;
597  default: assert(false);
598  }
599  reg.registerVar(self.make_id(*d).c_str(), snm.c_str(), tp, nm, &self.ports[d->index],
600  d->dflt, d->low, d->up, d->step);
601  }
602  }
603  self.idd = self.pd->id_str + ".dry_wet";
604  reg.registerVar(self.idd.c_str(),"","S","dry/wet",&self.dry_wet, 100, 0, 100, 1);
605  return 0;
606 }
607 
608 int LadspaDsp::uiloader(const UiBuilder& b, int form) {
609  if (!(form & UI_FORM_STACK)) {
610  return -1;
611  }
612  LadspaDsp& self = *static_cast<LadspaDsp*>(b.plugin);
613  b.openHorizontalhideBox("");
614  if (self.pd->master_idx >= 0) {
615  int n = 0;
616  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
617  if ((n)==self.pd->master_idx) {
618  switch ((*it)->tp) {
619  case tp_enum:
620  b.create_selector_no_caption(self.make_id(*self.pd->names[self.pd->master_idx]).c_str());
621  break;
622  default:
623  const char *p = self.pd->master_label.c_str();
624  if (!*p) {
625  p = "";
626  }
627  b.create_master_slider(self.make_id(*self.pd->names[self.pd->master_idx]).c_str(), p);
628  break;
629  }
630  }
631  }
632  }
633  int rows = 0;
634  int n = 0;
635  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
636  if ((*it)->newrow) {
637  rows +=1;
638  }
639  }
640  b.closeBox();
641  b.openVerticalBox("");
642  if (rows > 0) {
643  b.insertSpacer();
644  b.insertSpacer();
645  }
646  b.openHorizontalBox("");
647  n = 0;
648  int row = 0;
649  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
650  if ((*it)->newrow) {
651  b.closeBox();
652  if ( (rows == 1) || ( rows > 1 && row > 0 )) {
653  b.insertSpacer();
654  b.insertSpacer();
655  b.insertSpacer();
656  }
657  b.openHorizontalBox("");
658  row +=1;
659  }
660  const char *p1 = self.desc->PortNames[(*it)->index];
661  if (!(*it)->name.empty())
662  p1 = (*it)->name.c_str();
663  Glib::ustring trim = TrimEffectLabel(p1, 4);
664  const char *p = trim.c_str();
665  std::string id = self.make_id(**it);
666  if ((row == 1 && rows == 1 ) || (row >1 && rows >1 )) {
668  }
669  switch ((*it)->tp) {
670  case tp_scale:
671  case tp_scale_log:
672  if (!(*it)->has_caption) {
673  p = "";
674  }
675  b.create_small_rackknobr(id.c_str(), p);
676  break;
677  case tp_enabled:
678  if ((*it)->has_caption) {
679  b.create_switch("switch",id.c_str(), "Power");
680  } else {
681  b.create_switch_no_caption("switchit",id.c_str());
682  }
683  break;
684  case tp_toggle:
685  if ((*it)->has_caption) {
686  b.create_switch("switch",id.c_str(), p);
687  } else {
688  b.create_switch_no_caption("switchit",id.c_str());
689  }
690  break;
691  case tp_display:
692  if (!(*it)->has_caption) {
693  p = "";
694  }
695  b.create_port_display(id.c_str(), p);
696  break;
697  case tp_display_toggle:
698  if ((*it)->has_caption) {
699  b.create_switch("led",id.c_str(), p);
700  } else {
701  b.create_switch_no_caption("led",id.c_str());
702  }
703  break;
704  case tp_int:
705  if (!(*it)->has_caption) {
706  p = "";
707  }
708  if (((*it)->up - (*it)->low)<200) {
709  b.create_small_rackknob(id.c_str(), p);
710  } else {
711  b.create_spin_value(id.c_str(), p);
712  }
713  break;
714  case tp_enum:
715  if ((*it)->has_caption) {
716  b.create_selector(id.c_str(), p);
717  } else {
718  b.create_selector_no_caption(id.c_str());
719  }
720  break;
721  case tp_none:
722  break;
723  default:
724  assert(false);
725  }
726  }
727  if (self.pd->add_wet_dry) {
728  b.create_small_rackknobr(self.idd.c_str(), "dry/wet");
729  }
730  b.closeBox();
731  b.closeBox();
732  return 0;
733 }
734 
735 void LadspaDsp::del_instance(PluginDef *plugin) {
736  delete static_cast<LadspaDsp*>(plugin);
737 }
738 
739 
740 /****************************************************************
741  ** class LV2Features
742  */
743 
744 static const int32_t min_block_length = 1;
745 static const int32_t max_block_length = 8192;
746 
747 
748 static std::vector<std::string> gx_uri_mapping = {
749  LV2_ATOM__Int,
750  LV2_ATOM__Long,
751  LV2_ATOM__Float,
752  LV2_ATOM__Double,
753  LV2_BUF_SIZE__maxBlockLength,
754  LV2_BUF_SIZE__minBlockLength,
755 };
756 
757 
758 LV2_Options_Option LV2Features::gx_options[2] = {
759  { LV2_OPTIONS_INSTANCE, 0, lv2_urid_map(NULL,LV2_BUF_SIZE__minBlockLength),
760  sizeof(int32_t), lv2_urid_map(NULL,LV2_ATOM__Int), &min_block_length },
761  { LV2_OPTIONS_INSTANCE, 0, lv2_urid_map(NULL,LV2_BUF_SIZE__maxBlockLength),
762  sizeof(int32_t), lv2_urid_map(NULL,LV2_ATOM__Int), &max_block_length },
763 };
764 
765 LV2_Feature LV2Features::gx_options_feature = {
766  LV2_OPTIONS__options, gx_options
767 };
768 
769 LV2_URID LV2Features::lv2_urid_map(LV2_URID_Map_Handle, const char* const uri_) {
770  if (uri_ == nullptr || uri_[0] == '\0') {
771  return 0;
772  }
773 
774  const std::string uri(uri_);
775 
776  LV2_URID urid = 1;
777  for (const std::string& uri2 : gx_uri_mapping)
778  {
779  if (uri2 == uri) {
780  //fprintf(stderr, "%s uri match\n", uri.c_str());
781  return urid;
782  }
783  ++urid;
784  }
785 
786  gx_uri_mapping.push_back(uri);
787  return urid;
788 }
789 
790 LV2_URID_Map LV2Features::gx_urid_map = {
791  NULL, lv2_urid_map
792 };
793 
794 LV2_Feature LV2Features::gx_urid_map_feature = {
795  LV2_URID__map, &gx_urid_map
796 };
797 
798 uint32_t LV2Features::lv2_uri_to_id(LV2_URI_Map_Callback_Data handle, const char*, const char* uri) {
799  return lv2_urid_map(handle, uri);
800 }
801 
802 LV2_URI_Map_Feature LV2Features::gx_uri_map = {
803  NULL, lv2_uri_to_id
804 };
805 
806 LV2_Feature LV2Features::gx_uri_map_feature = {
807  LV2_URI_MAP_URI, &gx_uri_map
808 };
809 
810 const char* LV2Features::lv2_urid_unmap(LV2_URID_Unmap_Handle, const LV2_URID urid) {
811  if (urid == 0 || urid >= gx_uri_mapping.size())
812  return nullptr;
813 
814  return gx_uri_mapping[urid-1].c_str();
815 }
816 
817 LV2_URID_Unmap LV2Features::gx_urid_unmap = {
818  NULL, lv2_urid_unmap
819 };
820 
821 LV2_Feature LV2Features::gx_urid_unmap_feature = {
822  LV2_URID__unmap, &gx_urid_unmap
823 };
824 
825 LV2_Feature* LV2Features::gx_features[] = {
826  &gx_urid_map_feature,
827  &gx_uri_map_feature,
828  &gx_urid_unmap_feature,
829  &gx_options_feature,
830  nullptr
831 };
832 
833 /****************************************************************
834  ** class Lv2Dsp
835  */
836 
837 class Lv2Dsp: public PluginDef {
838 private:
839  static void init(unsigned int samplingFreq, PluginDef *plugin);
840  static void mono_process(int count, float *input, float *output, PluginDef *plugin);
841  static void to_mono_process(int count, float *input, float *output, PluginDef *plugin);
842  static void stereo_process(int count, float *input1, float *input2, float *output1, float *output2, PluginDef *plugin);
843  static int activate(bool start, PluginDef *plugin);
844  static int registerparam(const ParamReg& reg);
845  static int uiloader(const UiBuilder& builder, int form);
846  static void del_instance(PluginDef *plugin);
847  //
848  const LadspaLoader& loader;
849  const LilvPlugin* plugin;
850  LilvNode* name_node;
851  LilvInstance* instance;
852  LADSPA_Data *ports;
853  Glib::ustring name_str;
854  Glib::ustring dest_str;
855  const plugdesc *pd;
856  bool is_activated;
857  void connect(const LilvNode* tp, int i, float *v);
858  inline void cleanup();
859  void set_shortname();
860  float dry_wet;
861  std::string idd;
862  void set_enabled(bool v,Parameter& p);
863  inline void mono_dry_wet(int count, float *input0, float *input1, float *output0);
864  inline void stereo_dry_wet(int count, float *input0, float *input1, float *input2, float *input3, float *output0, float *output1);
865  inline void down_to_mono(int count, float *input0, float *input1, float *output0);
866  inline void up_to_stereo(int count, float *input0, float *output0, float *output1);
867  std::string make_id(const paradesc& p);
868  Lv2Dsp(const plugdesc *plug, const LilvPlugin* plugin_, const LadspaLoader& loader_, bool mono, bool to_mono);
869  ~Lv2Dsp();
870 public:
871  static Lv2Dsp *create(const plugdesc *plug, const LadspaLoader& loader);
872  void set_plugdesc(const plugdesc* pd_);
873 };
874 
875 Lv2Dsp *Lv2Dsp::create(const plugdesc *plug, const LadspaLoader& loader) {
876  LilvNode* plugin_uri = lilv_new_uri(loader.world, plug->path.c_str());
877  const LilvPlugin* plugin = lilv_plugins_get_by_uri(loader.lv2_plugins, plugin_uri);
878  lilv_node_free(plugin_uri);
879  if (!plugin) {
880  gx_print_error("lv2loader",ustring::compose(_("Cannot open LV2 plugin: %1"), plug->path));
881  return NULL;
882  }
883 
884  int num_inputs = lilv_plugin_get_num_ports_of_class(plugin, loader.lv2_AudioPort, loader.lv2_InputPort, 0);
885  int num_outputs = lilv_plugin_get_num_ports_of_class(plugin, loader.lv2_AudioPort, loader.lv2_OutputPort, 0);
886  int num_controls = lilv_plugin_get_num_ports_of_class(plugin, loader.lv2_ControlPort, 0);
887 
888  bool mono;
889  bool to_mono = false;
890  if (num_inputs == 1 && num_outputs == 1) {
891  mono = true;
892  } else if (num_inputs == 2 && num_outputs == 2) {
893  mono = false;
894  if (plug->stereo_to_mono) to_mono = true;
895  } else {
896  LilvNode *nm = lilv_plugin_get_name(plugin);
898  "lv2loader",ustring::compose(
899  _("cannot use LV2 plugin %1 with %2 inputs and %3 outputs"),
900  lilv_node_as_string(nm), num_inputs, num_outputs));
901  lilv_node_free(nm);
902  return NULL;
903  }
904  Lv2Dsp* self = new Lv2Dsp(plug, plugin, loader, mono, to_mono);
905  int desk_controls = 0;
906  for (std::vector<paradesc*>::const_iterator it = self->pd->names.begin(); it != self->pd->names.end(); ++it, ++desk_controls) ;
907  if (num_controls != desk_controls) {
908  LilvNode *nm = lilv_plugin_get_name(plugin);
910  "lv2loader",ustring::compose(
911  _("LV2 plugin %1 has changed it's ports, this may result in errors!!\nPlease go to the LADSPA/LV2 loader and select %1\nSelect 'Show Details' and press 'Restore Defaults'\nUn-load %1 (un-tick the box) and press 'save'.\nAfter this you could re-load %1 with it's new ports"),
912  lilv_node_as_string(nm)));
913  lilv_node_free(nm);
914  }
915  PluginDef& pl = *static_cast<PluginDef*>(self);
916  pl.flags |=PGNI_IS_LV2;
917  return self;
918 }
919 
920 Lv2Dsp::Lv2Dsp(const plugdesc *plug, const LilvPlugin* plugin_, const LadspaLoader& loader_, bool mono, bool to_mono)
921  : PluginDef(), loader(loader_), plugin(plugin_), name_node(lilv_plugin_get_name(plugin_)), instance(),
922  ports(new LADSPA_Data[lilv_plugin_get_num_ports(plugin_)]), name_str(), dest_str(), pd(plug), is_activated(false) {
924  id = pd->id_str.c_str();
925  category = pd->category.c_str();
926  dest_str = "LV2 ";
927  dest_str += lilv_node_as_string(name_node);
928  LilvNode *nd = lilv_plugin_get_author_name(plugin);
929  if (!nd) {
930  nd = lilv_plugin_get_project(plugin);
931  }
932  if (nd) {
933  dest_str += " by ";
934  dest_str += lilv_node_as_string(nd);
935  }
936  lilv_node_free(nd);
937  description = dest_str.c_str();
938  name = lilv_node_as_string(name_node);
939  set_shortname();
940  set_samplerate = init;
941  if (mono) {
942  mono_audio = mono_process;
943  } else {
944  if (to_mono) mono_audio = to_mono_process;
945  else stereo_audio = stereo_process;
946  }
947  activate_plugin = activate;
948  register_params = registerparam;
949  load_ui = uiloader;
950  delete_instance = del_instance;
951 }
952 
953 inline void Lv2Dsp::cleanup() {
954  if (instance) {
955  if (pd->quirks & need_activate) {
956  activate(true, this);
957  }
958  activate(false, this);
959  if (!(pd->quirks & no_cleanup)) {
960  lilv_instance_free(instance);
961  }
962  instance = 0;
963  }
964 }
965 
966 Lv2Dsp::~Lv2Dsp() {
967  cleanup();
968  delete[] ports;
969  lilv_node_free(name_node);
970 }
971 
972 int Lv2Dsp::activate(bool start, PluginDef *plugin) {
973  Lv2Dsp& self = *static_cast<Lv2Dsp*>(plugin);
974  if (start == self.is_activated) {
975  return 0;
976  }
977  if (!self.instance) {
978  gx_print_warning("Lv2Dsp", ustring::compose("cant activate plugin %1", self.name));
979  return 1;
980  }
981  self.is_activated = start;
982  if (start) {
983  lilv_instance_activate(self.instance);
984  } else {
985  lilv_instance_deactivate(self.instance);
986  }
987  return 0;
988 }
989 
990 void Lv2Dsp::connect(const LilvNode* tp, int i, float *v) {
991  unsigned int num_ports = lilv_plugin_get_num_ports(plugin);
992  for (unsigned int n = 0; n < num_ports; ++n) {
993  const LilvPort* port = lilv_plugin_get_port_by_index(plugin, n);
994  if (!lilv_port_is_a(plugin, port, loader.lv2_AudioPort)) {
995  continue;
996  }
997  if (lilv_port_is_a(plugin, port, tp)) {
998  if (i == 0) {
999  lilv_instance_connect_port(instance, n, v);
1000  return;
1001  }
1002  i -= 1;
1003  }
1004  }
1005  gx_print_error("lv2loader", _("audio port not found"));
1006 }
1007 
1008 void Lv2Dsp::set_plugdesc(const plugdesc* pd_) {
1009  pd = pd_;
1010  id = pd->id_str.c_str();
1011  category = pd->category.c_str();
1012  set_shortname();
1013 }
1014 
1015 void Lv2Dsp::set_shortname() {
1016  if (!pd->shortname.empty()) {
1017  shortname = pd->shortname.c_str();
1018  } else {
1019  name_str = lilv_node_as_string(name_node);
1020  if (name_str.size() > 15) {
1021  name_str.erase(15);
1022  }
1023  shortname = name_str.c_str();
1024  }
1025 }
1026 
1027 
1028 void Lv2Dsp::init(unsigned int samplingFreq, PluginDef *pldef) {
1029  Lv2Dsp& self = *static_cast<Lv2Dsp*>(pldef);
1030  self.cleanup();
1031  if (samplingFreq == 0) {
1032  return;
1033  }
1034  self.instance = lilv_plugin_instantiate(self.plugin, samplingFreq, LV2Features::getInstance().gx_features);
1035  if (!self.instance) {
1036  gx_print_error("Lv2Dsp", ustring::compose("cant init plugin: %1 \n uri: %2", self.name, self.pd->path));
1037  return;
1038  }
1039  int n = 0;
1040  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
1041  lilv_instance_connect_port(self.instance, (*it)->index, &self.ports[(*it)->index]);
1042  }
1043 }
1044 
1045 inline void Lv2Dsp::mono_dry_wet(int count, float *input0, float *input1, float *output0)
1046 {
1047  double fSlow0 = (0.01 * dry_wet);
1048  double fSlow1 = (1 - fSlow0);
1049  for (int i=0; i<count; i++) {
1050  output0[i] = ((fSlow0 * (double)input1[i]) + (fSlow1 * (double)input0[i]));
1051  }
1052 }
1053 
1054 void Lv2Dsp::mono_process(int count, float *input, float *output, PluginDef *plugin) {
1055  Lv2Dsp& self = *static_cast<Lv2Dsp*>(plugin);
1056  assert(self.is_activated);
1057  if (self.pd->add_wet_dry) {
1058  float wet_out[count];
1059  self.connect(self.loader.lv2_InputPort, 0, input);
1060  self.connect(self.loader.lv2_OutputPort, 0, wet_out);
1061  lilv_instance_run(self.instance, count);
1062  self.mono_dry_wet(count, input, wet_out, output);
1063  } else {
1064  self.connect(self.loader.lv2_InputPort, 0, input);
1065  self.connect(self.loader.lv2_OutputPort, 0, output);
1066  lilv_instance_run(self.instance, count);
1067  }
1068 }
1069 
1070 void Lv2Dsp::up_to_stereo(int count, float *input0, float *output0, float *output1) {
1071  memcpy(output0, input0, count * sizeof(float));
1072  memcpy(output1, input0, count * sizeof(float));
1073 }
1074 
1075 void Lv2Dsp::down_to_mono(int count, float *input0, float *input1, float *output0) {
1076  for (int i=0; i<count; i++) {
1077  output0[i] = 0.5 * (input0[i] + input1[i]);
1078  }
1079 }
1080 
1081 void Lv2Dsp::to_mono_process(int count, float *input, float *output, PluginDef *plugin) {
1082  Lv2Dsp& self = *static_cast<Lv2Dsp*>(plugin);
1083  assert(self.is_activated);
1084  if (self.pd->add_wet_dry) {
1085  float wet_out[count];
1086  float inputs[count];
1087  float inputs1[count];
1088  float outputs[count];
1089  float outputs1[count];
1090  self.up_to_stereo(count,input,inputs, inputs1);
1091  self.connect(self.loader.lv2_InputPort, 0, inputs);
1092  self.connect(self.loader.lv2_InputPort, 1, inputs1);
1093  self.connect(self.loader.lv2_OutputPort, 0, outputs);
1094  self.connect(self.loader.lv2_OutputPort, 1, outputs1);
1095  lilv_instance_run(self.instance, count);
1096  self.down_to_mono(count,outputs,outputs1,wet_out);
1097  self.mono_dry_wet(count, input, wet_out, output);
1098  } else {
1099  float inputs[count];
1100  float inputs1[count];
1101  float outputs[count];
1102  float outputs1[count];
1103  self.up_to_stereo(count,input,inputs, inputs1);
1104  self.connect(self.loader.lv2_InputPort, 0, inputs);
1105  self.connect(self.loader.lv2_InputPort, 1, inputs1);
1106  self.connect(self.loader.lv2_OutputPort, 0, outputs);
1107  self.connect(self.loader.lv2_OutputPort, 1, outputs1);
1108  lilv_instance_run(self.instance, count);
1109  self.down_to_mono(count,outputs,outputs1,output);
1110  }
1111 }
1112 
1113 inline void Lv2Dsp::stereo_dry_wet(int count, float *input0, float *input1, float *input2, float *input3, float *output0, float *output1)
1114 {
1115  double fSlow0 = (0.01 * dry_wet);
1116  double fSlow1 = (1 - fSlow0);
1117  for (int i=0; i<count; i++) {
1118  output0[i] = ((fSlow0 * (double)input2[i]) + (fSlow1 * (double)input0[i]));
1119  output1[i] = ((fSlow0 * (double)input3[i]) + (fSlow1 * (double)input1[i]));
1120  }
1121 }
1122 
1123 void Lv2Dsp::stereo_process(int count, float *input1, float *input2, float *output1, float *output2, PluginDef *plugin) {
1124  Lv2Dsp& self = *static_cast<Lv2Dsp*>(plugin);
1125  assert(self.is_activated);
1126  if (self.pd->add_wet_dry) {
1127  float wet_out1[count];
1128  float wet_out2[count];
1129  self.connect(self.loader.lv2_InputPort, 0, input1);
1130  self.connect(self.loader.lv2_InputPort, 1, input2);
1131  self.connect(self.loader.lv2_OutputPort, 0, wet_out1);
1132  self.connect(self.loader.lv2_OutputPort, 1, wet_out2);
1133  lilv_instance_run(self.instance, count);
1134  self.stereo_dry_wet(count, input1, input2, wet_out1, wet_out2, output1, output2);
1135  } else {
1136  self.connect(self.loader.lv2_InputPort, 0, input1);
1137  self.connect(self.loader.lv2_InputPort, 1, input2);
1138  self.connect(self.loader.lv2_OutputPort, 0, output1);
1139  self.connect(self.loader.lv2_OutputPort, 1, output2);
1140  lilv_instance_run(self.instance, count);
1141  }
1142 }
1143 
1144 std::string Lv2Dsp::make_id(const paradesc& p) {
1145  return pd->id_str + "." + to_string(p.index);
1146 }
1147 
1148 void Lv2Dsp::set_enabled(bool v,Parameter& p) {
1149  if(v) {
1150  p.getFloat().set(1.0);
1151  } else {
1152  p.getFloat().set(0.0);
1153  }
1154 }
1155 
1156 int Lv2Dsp::registerparam(const ParamReg& reg) {
1157  Lv2Dsp& self = *static_cast<Lv2Dsp*>(reg.plugin);
1158  int n = 0;
1159  int cnt_in_row = 0;
1160  int left = 0;
1161  int num_controls = lilv_plugin_get_num_ports_of_class(self.plugin, self.loader.lv2_ControlPort, 0);
1162  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
1163  if (n>=num_controls) break;
1164  paradesc *d = *it;
1165  if (d->tp != tp_none) {
1166  left -= 1;
1167  if (left < 0) {
1168  cnt_in_row = 1;
1169  std::vector<paradesc*>::const_iterator it2 = it+1;
1170  while (it2 != self.pd->names.end() && !(*it2)->newrow) {
1171  if ((*it2)->tp != tp_none) {
1172  ++cnt_in_row;
1173  }
1174  ++it2;
1175  }
1176  left = cnt_in_row;
1177  }
1178  }
1179  const LilvPort* port = lilv_plugin_get_port_by_index(self.plugin, d->index);
1180  LilvNode* nm_node = lilv_port_get_name(self.plugin, port);
1181  const char *nm = lilv_node_as_string(nm_node);
1182  Glib::ustring snm(d->name);
1183  if (snm.empty() && d->tp != tp_none) {
1184  snm = TrimLabel(nm, cnt_in_row);
1185  }
1186  if (d->tp == tp_enum) {
1187  reg.registerEnumVar(self.make_id(*d).c_str(), snm.c_str(), "S", nm, d->values, &self.ports[d->index],
1188  d->dflt, d->low, d->up, d->step);
1189  } else if (d->tp == tp_enabled) {
1190  reg.registerVar(self.make_id(*d).c_str(), snm.c_str(),"BA" , nm, &self.ports[d->index],
1191  d->dflt, d->low, d->up, d->step);
1192  ParamMap& pmap = self.loader.get_parameter_map();
1193  pmap[self.pd->id_str + ".on_off"].signal_changed_bool().connect(
1194  sigc::bind(sigc::mem_fun(self, &Lv2Dsp::set_enabled),sigc::ref(pmap[self.make_id(*d)])));
1195 
1196  } else {
1197  const char *tp = 0;
1198  switch (d->tp) {
1199  case tp_none: tp = "S"; break;
1200  case tp_int: tp = "S"; break;
1201  case tp_scale: tp = "S"; break;
1202  case tp_scale_log: tp = "SL"; break;
1203  case tp_toggle: tp = "B"; break;
1204  case tp_display: tp = "SO"; break;
1205  case tp_display_toggle: tp = "BO"; break;
1206  default: assert(false);
1207  }
1208  reg.registerVar(self.make_id(*d).c_str(), snm.c_str(), tp, nm, &self.ports[d->index],
1209  d->dflt, d->low, d->up, d->step);
1210  }
1211  lilv_node_free(nm_node);
1212  }
1213  self.idd = self.pd->id_str + ".dry_wet";
1214  reg.registerVar(self.idd.c_str(),"","S","dry/wet",&self.dry_wet, 100, 0, 100, 1);
1215  return 0;
1216 }
1217 
1218 int Lv2Dsp::uiloader(const UiBuilder& b, int form) {
1219  if (!(form & UI_FORM_STACK)) {
1220  return -1;
1221  }
1222  Lv2Dsp& self = *static_cast<Lv2Dsp*>(b.plugin);
1223  b.openHorizontalhideBox("");
1224  if (self.pd->master_idx >= 0) {
1225  int n = 0;
1226  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
1227  if ((n)==self.pd->master_idx) {
1228  switch ((*it)->tp) {
1229  case tp_enum:
1230  b.create_selector_no_caption(self.make_id(*self.pd->names[self.pd->master_idx]).c_str());
1231  break;
1232  default:
1233  const char *p = self.pd->master_label.c_str();
1234  if (!*p) {
1235  p = "";
1236  }
1237  b.create_master_slider(self.make_id(*self.pd->names[self.pd->master_idx]).c_str(), p);
1238  break;
1239  }
1240  }
1241  }
1242  }
1243  b.closeBox();
1244  b.openVerticalBox("");
1245  b.openHorizontalBox("");
1246  int rows = 0;
1247  int n = 0;
1248  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
1249  if ((*it)->newrow) {
1250  rows +=1;
1251  }
1252  }
1253  n = 0;
1254  int row = 0;
1255  int num_controls = lilv_plugin_get_num_ports_of_class(self.plugin, self.loader.lv2_ControlPort, 0);
1256  for (std::vector<paradesc*>::const_iterator it = self.pd->names.begin(); it != self.pd->names.end(); ++it, ++n) {
1257  if (n>=num_controls) break;
1258  if ((*it)->newrow) {
1259  b.closeBox();
1260  if ( (rows == 1) || ( rows > 1 && row > 0 )) {
1261  b.insertSpacer();
1262  b.insertSpacer();
1263  b.insertSpacer();
1264  }
1265  b.openHorizontalBox("");
1266  row +=1;
1267  }
1268  const LilvPort* port = lilv_plugin_get_port_by_index(self.plugin, (*it)->index);
1269  LilvNode* nm_node = lilv_port_get_name(self.plugin, port);
1270  const char *p1 = lilv_node_as_string(nm_node);
1271  if (!(*it)->name.empty())
1272  p1 = (*it)->name.c_str();
1273  Glib::ustring trim = TrimEffectLabel(p1, 4);
1274  const char *p = trim.c_str();
1275  std::string id = self.make_id(**it);
1276  if (num_controls<30) {
1277  if ((row == 1 && rows == 1 ) || (row >1 && rows >1 )) {
1279  }
1280  } else if (num_controls<35) {
1281  if ((row == 2 && rows == 2 ) || (row >2 && rows >2 )) {
1283  }
1284  } else {
1285  if ((row == 3 && rows == 3 ) || (row >3 && rows >3 )) {
1287  }
1288  }
1289  switch ((*it)->tp) {
1290  case tp_scale:
1291  case tp_scale_log:
1292  if (!(*it)->has_caption) {
1293  p = "";
1294  }
1295  b.create_small_rackknobr(id.c_str(), p);
1296  break;
1297  case tp_enabled:
1298  break;
1299  case tp_toggle:
1300  if ((*it)->has_caption) {
1301  b.create_switch("switch_mid",id.c_str(), p);
1302  } else {
1303  b.create_switch_no_caption("switchit",id.c_str());
1304  }
1305  break;
1306  case tp_display:
1307  if (!(*it)->has_caption) {
1308  p = "";
1309  }
1310  b.create_port_display(id.c_str(), p);
1311  break;
1312  case tp_display_toggle:
1313  if ((*it)->has_caption) {
1314  b.create_switch("led",id.c_str(), p);
1315  } else {
1316  b.create_switch_no_caption("led",id.c_str());
1317  }
1318  break;
1319  case tp_int:
1320  if (!(*it)->has_caption) {
1321  p = "";
1322  }
1323  if (((*it)->up - (*it)->low)<200) {
1324  b.create_small_rackknob(id.c_str(), p);
1325  } else {
1326  b.create_spin_value(id.c_str(), p);
1327  }
1328  break;
1329  case tp_enum:
1330  if ((*it)->has_caption) {
1331  b.create_selector(id.c_str(), p);
1332  } else {
1333  b.create_selector_no_caption(id.c_str());
1334  }
1335  break;
1336  case tp_none:
1337  break;
1338  default:
1339  assert(false);
1340  }
1341  lilv_node_free(nm_node);
1342  }
1343  if (self.pd->add_wet_dry) {
1344  b.create_small_rackknobr(self.idd.c_str(), "dry/wet");
1345  }
1346  b.closeBox();
1347  b.closeBox();
1348  return 0;
1349 }
1350 
1351 void Lv2Dsp::del_instance(PluginDef *plugin) {
1352  delete static_cast<Lv2Dsp*>(plugin);
1353 }
1354 
1355 
1356 /****************************************************************
1357  ** class LadspaLoader
1358  */
1359 
1361  if (p->quirks & is_lv2) {
1362  return Lv2Dsp::create(p, *this);
1363  } else {
1364  return LadspaDsp::create(p);
1365  }
1366 }
1367 
1369  : options(options_),
1370  plugins(),
1371  world(lilv_world_new()),
1372  param(param_),
1373  lv2_plugins(),
1374  lv2_AudioPort(lilv_new_uri(world, LV2_CORE__AudioPort)),
1375  lv2_ControlPort(lilv_new_uri(world, LV2_CORE__ControlPort)),
1376  lv2_InputPort(lilv_new_uri(world, LV2_CORE__InputPort)),
1377  lv2_OutputPort(lilv_new_uri(world, LV2_CORE__OutputPort)) {
1378  lilv_world_load_all(world);
1379  lv2_plugins = lilv_world_get_all_plugins(world);
1380  load(plugins);
1381 }
1382 
1384  for (pluginarray::iterator i = plugins.begin(); i != plugins.end(); ++i) {
1385  delete *i;
1386  }
1387  lilv_node_free(lv2_OutputPort);
1388  lilv_node_free(lv2_InputPort);
1389  lilv_node_free(lv2_ControlPort);
1390  lilv_node_free(lv2_AudioPort);
1391  lilv_world_free(world);
1392 }
1393 
1395  try {
1396  read_module_list(ml);
1397  } catch (JsonException &e) {
1398  gx_print_error("ladspaloader",ustring::compose(_("Exception in LADSPA list reader: %1"), e.what()));
1399  return false;
1400  }
1401  return true;
1402 }
1403 
1405  for (pluginarray::iterator i = plugins.begin(); i != plugins.end(); ++i) {
1406  delete *i;
1407  }
1408  plugins = new_plugins;
1409 }
1410 
1412  //for (pluginarray::iterator i = plugins.begin(); i != plugins.end(); ++i) {
1413  //delete *i;
1414  //}
1415  plugins = new_plugins;
1416 }
1417 
1418 LadspaLoader::pluginarray::iterator LadspaLoader::find(plugdesc *desc) {
1419  for (pluginarray::iterator i = begin(); i != end(); ++i) {
1420  if (desc->quirks & is_lv2) {
1421  if ((*i)->path == desc->path) {
1422  return i;
1423  }
1424  } else {
1425  if ((*i)->UniqueID == desc->UniqueID) {
1426  return i;
1427  }
1428  }
1429  }
1430  return end();
1431 }
1432 
1434  if (pdesc->quirks & is_lv2) {
1435  static_cast<Lv2Dsp*>(pdef)->set_plugdesc(pdesc);
1436  } else {
1437  static_cast<LadspaDsp*>(pdef)->set_plugdesc(pdesc);
1438  }
1439 }
1440 
1442  for (value_pair *p = values; p->value_id; ++p) {
1443  g_free(const_cast<char*>(p->value_id));
1444  }
1445  delete[] values;
1446 }
1447 
1448 void paradesc::set_valuelist(const std::vector<std::string>& v) {
1449  values = new value_pair[v.size()+1];
1450  int n = 0;
1451  for (std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i, ++n) {
1452  const char *p = g_strdup(i->c_str());
1453  values[n].value_id = p;
1454  values[n].value_label = p;
1455  }
1456  values[n].value_id = 0;
1457  values[n].value_label = 0;
1458 }
1459 
1460 void LadspaLoader::read_module_config(const std::string& filename, plugdesc *p) {
1461  std::ifstream ifs(filename.c_str());
1462  if (ifs.fail()) {
1463  gx_print_error("ladspaloader", ustring::compose(_("can't open %1"), filename));
1464  return;
1465  }
1466  gx_system::JsonParser jp(&ifs);
1469  jp.current_value_int(); // int version
1471  p->shortname = jp.current_value();
1473  p->category = jp.current_value();
1475  p->master_idx = jp.current_value_int();
1477  p->master_label = jp.current_value();
1479  p->quirks = jp.current_value_int();
1481  p->add_wet_dry= jp.current_value_int();
1482  // new monobox for stereo plugs
1483  if (jp.peek() == gx_system::JsonParser::value_number) {
1485  p->stereo_to_mono= jp.current_value_int();
1486  }
1488  while (jp.peek() != gx_system::JsonParser::end_array) {
1489  paradesc *para = new paradesc;
1492  para->index = jp.current_value_int();
1493  jp.skip_object(); // meta data
1495  para->name = jp.current_value();
1496  jp.next(gx_system::JsonParser::value_number); // use_sr
1498  para->dflt = jp.current_value_float();
1500  para->low = jp.current_value_float();
1502  para->up = jp.current_value_float();
1504  para->step = jp.current_value_float();
1506  para->tp = static_cast<widget_type>(jp.current_value_int()); //FIXME (check valid)
1508  para->newrow = jp.current_value_int();
1510  para->has_caption = jp.current_value_int();
1512  std::vector<std::string> v;
1513  while (jp.peek() != gx_system::JsonParser::end_array) {
1515  v.push_back(jp.current_value());
1516  }
1518  para->set_valuelist(v);
1520  p->names.push_back(para);
1521  }
1523  jp.close();
1524  ifs.close();
1525 }
1526 
1527 void LadspaLoader::read_module_list(pluginarray& ml) {
1528  std::ifstream ifs(options.get_user_filepath("ladspa_defs.js").c_str());
1529  if (ifs.fail()) {
1530  return;
1531  }
1532  gx_system::JsonParser jp(&ifs);
1534  while (jp.peek() != gx_system::JsonParser::end_array) {
1537  plugdesc *p = new plugdesc;
1538  p->path = jp.current_value();
1540  int idx = jp.current_value_int();
1541  if (idx < 0) {
1542  p->quirks |= is_lv2;
1543  }
1544  p->index = idx;
1546  p->UniqueID = jp.current_value_int();
1548  p->Label = jp.current_value();
1550  std::string s;
1551  if (idx < 0) {
1552  s = gx_system::encode_filename(p->path) + ".js";
1553  } else {
1554  s = get_ladspa_filename(p->UniqueID);
1555  }
1556  std::string fname = options.get_plugin_filepath(s);
1557  if (access(fname.c_str(), F_OK) != 0) {
1558  fname = options.get_factory_filepath(s);
1559  if (access(fname.c_str(), F_OK) != 0) {
1560  fname = "";
1561  }
1562  }
1563  if (!fname.empty()) {
1564  try {
1565  read_module_config(fname, p);
1566  } catch (JsonException &e) {
1567  gx_print_error("ladspaloader",ustring::compose(_("read error in file %1: %2"), s, e.what()));
1568  }
1569  }
1570  if (p->quirks & is_lv2) {
1571  p->id_str = "lv2_" + gx_system::encode_filename(p->path);
1572  } else {
1573  p->id_str = "ladspa_" + to_string(p->UniqueID);
1574  }
1575  ml.push_back(p);
1576  }
1577  jp.close();
1578  ifs.close();
1579 }
1580 
1581 } // namespace gx_engine
gx_engine::paradesc::set_valuelist
void set_valuelist(const std::vector< std::string > &v)
Definition: ladspaplugin.cpp:1448
gx_engine::tp_enabled
@ tp_enabled
Definition: gx_internal_plugins.h:704
gx_system::JsonParser::value_key
@ value_key
Definition: gx_json.h:130
gx_system::BasicOptions::get_user_filepath
std::string get_user_filepath(const std::string &basename) const
Definition: gx_system.h:371
UiBuilder::create_port_display
void(* create_port_display)(const char *id, const char *label)
Definition: gx_plugin.h:92
gx_system::JsonParser::begin_object
@ begin_object
Definition: gx_json.h:124
LADSPA_PORT_OUTPUT
#define LADSPA_PORT_OUTPUT
Definition: ladspa.h:158
PluginDef::set_samplerate
inifunc set_samplerate
Definition: gx_plugin.h:200
gx_system::JsonWriter::begin_object
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
gx_system::encode_filename
std::string encode_filename(const std::string &s)
Definition: gx_system.cpp:1013
gx_engine::LV2Features::gx_features
static LV2_Feature * gx_features[]
Definition: gx_internal_plugins.h:691
gx_system::JsonParser::value_string
@ value_string
Definition: gx_json.h:128
PluginDef::mono_audio
process_mono_audio mono_audio
Definition: gx_plugin.h:197
gx_engine::plugdesc::master_label
Glib::ustring master_label
Definition: gx_internal_plugins.h:736
UiBuilder::openVerticalBox
void(* openVerticalBox)(const char *label)
Definition: gx_plugin.h:68
gx_engine::LadspaLoader::update_instance
void update_instance(PluginDef *pdef, plugdesc *pdesc)
Definition: ladspaplugin.cpp:1433
UiBuilder::create_switch_no_caption
void(* create_switch_no_caption)(const char *sw_type, const char *id)
Definition: gx_plugin.h:89
gx_engine::LadspaDsp::create
static LadspaDsp * create(const plugdesc *plug)
Definition: ladspaplugin.cpp:71
gx_engine::plugdesc::category
Glib::ustring category
Definition: gx_internal_plugins.h:731
value_pair
Definition: gx_plugin.h:117
PluginDef::category
const char * category
Definition: gx_plugin.h:192
gx_engine::LV2Features::gx_urid_unmap
static LV2_URID_Unmap gx_urid_unmap
Definition: gx_internal_plugins.h:693
gx_engine::LadspaDsp
Definition: ladspaplugin.cpp:35
PluginDef::register_params
registerfunc register_params
Definition: gx_plugin.h:202
gx_engine::plugdesc
Definition: gx_internal_plugins.h:724
PluginDef::shortname
const char * shortname
Definition: gx_plugin.h:193
PluginDef::version
int version
Definition: gx_plugin.h:184
_LADSPA_Descriptor::PortCount
unsigned long PortCount
Definition: ladspa.h:406
gx_engine::PGNI_IS_LADSPA
@ PGNI_IS_LADSPA
Definition: gx_pluginloader.h:46
gx_system::CmdlineOptions::get_plugin_filepath
std::string get_plugin_filepath(const std::string &basename) const
Definition: gx_system.h:466
gx_engine::plugdesc::names
std::vector< paradesc * > names
Definition: gx_internal_plugins.h:737
gx_system::JsonParser::current_value
string current_value() const
Definition: gx_json.h:143
ParamReg::plugin
PluginDef * plugin
Definition: gx_plugin.h:123
gx_engine::plugdesc::UniqueID
unsigned long UniqueID
Definition: gx_internal_plugins.h:728
PluginDef::load_ui
uiloader load_ui
Definition: gx_plugin.h:203
gx_engine::no_cleanup
@ no_cleanup
Definition: gx_internal_plugins.h:722
gx_system::JsonWriter::write
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
gx_engine::plugdesc::writeJSON
void writeJSON(gx_system::JsonWriter &jw)
Definition: ladspaplugin.cpp:268
gx_engine::paradesc::newrow
bool newrow
Definition: gx_internal_plugins.h:712
gx_engine::LV2Features::gx_urid_map
static LV2_URID_Map gx_urid_map
Definition: gx_internal_plugins.h:692
PluginDef::stereo_audio
process_stereo_audio stereo_audio
Definition: gx_plugin.h:198
gx_system::CmdlineOptions::get_factory_filepath
std::string get_factory_filepath(const std::string &basename) const
Definition: gx_system.h:467
gx_system::JsonException::what
virtual const char * what() const
Definition: gx_json.h:49
gx_print_warning
void gx_print_warning(const char *, const std::string &)
Definition: gx_logging.cpp:161
_LADSPA_Descriptor::Maker
const char * Maker
Definition: ladspa.h:397
gx_engine::tp_display_toggle
@ tp_display_toggle
Definition: gx_internal_plugins.h:704
ParamReg::registerVar
float *(* registerVar)(const char *id, const char *name, const char *tp, const char *tooltip, float *var, float val, float low, float up, float step)
Definition: gx_plugin.h:124
PluginDef::name
const char * name
Definition: gx_plugin.h:188
gx_engine::LadspaLoader::begin
pluginarray::iterator begin()
Definition: gx_internal_plugins.h:771
gx_engine::plugdesc::add_wet_dry
int add_wet_dry
Definition: gx_internal_plugins.h:733
gx_engine::LadspaLoader::change_plugins
void change_plugins(pluginarray &new_plugins)
Definition: ladspaplugin.cpp:1404
gx_engine::paradesc
Definition: gx_internal_plugins.h:704
PluginDef::delete_instance
deletefunc delete_instance
Definition: gx_plugin.h:206
ParamReg::registerEnumVar
void(* registerEnumVar)(const char *id, const char *name, const char *tp, const char *tooltip, const value_pair *values, float *var, float val, float low, float up, float step)
Definition: gx_plugin.h:132
gx_engine::plugdesc::Label
Glib::ustring Label
Definition: gx_internal_plugins.h:729
gx_engine::plugdesc::shortname
Glib::ustring shortname
Definition: gx_internal_plugins.h:730
gx_engine::LadspaLoader
Definition: gx_internal_plugins.h:748
gx_engine::widget_type
widget_type
Definition: gx_internal_plugins.h:702
PluginDef
Definition: gx_plugin.h:183
gx_system::JsonException
Definition: gx_json.h:40
_LADSPA_Descriptor::connect_port
void(* connect_port)(LADSPA_Handle Instance, unsigned long Port, LADSPA_Data *DataLocation)
Definition: ladspa.h:466
gx_system::to_string
std::string to_string(const T &t)
Definition: gx_system.h:529
gx_system::JsonWriter::end_object
void end_object(bool nl=false)
Definition: gx_json.cpp:176
UiBuilder::create_spin_value
void(* create_spin_value)(const char *id, const char *label)
Definition: gx_plugin.h:91
UiBuilder::create_small_rackknob
void(* create_small_rackknob)(const char *id, const char *label)
Definition: gx_plugin.h:86
gx_engine::plugdesc::index
unsigned int index
Definition: gx_internal_plugins.h:727
gx_system::JsonParser::next
token next(token expect=no_token)
Definition: gx_json.cpp:496
gx_engine::paradesc::values
value_pair * values
Definition: gx_internal_plugins.h:714
gx_engine::LadspaLoader::get_ladspa_filename
static std::string get_ladspa_filename(unsigned long uid)
Definition: gx_internal_plugins.h:777
UiBuilder::create_small_rackknobr
void(* create_small_rackknobr)(const char *id, const char *label)
Definition: gx_plugin.h:98
gx_engine::PGNI_IS_LV2
@ PGNI_IS_LV2
Definition: gx_pluginloader.h:45
gx_engine
Definition: gx_convolver.h:33
UiBuilder::create_selector_no_caption
void(* create_selector_no_caption)(const char *id)
Definition: gx_plugin.h:88
gx_system::JsonWriter::write_kv
void write_kv(const char *key, float v)
Definition: gx_json.h:81
UiBuilder::plugin
PluginDef * plugin
Definition: gx_plugin.h:64
gx_system::JsonWriter
Definition: gx_json.h:55
_LADSPA_Descriptor::PortDescriptors
const LADSPA_PortDescriptor * PortDescriptors
Definition: ladspa.h:410
gx_engine::paradesc::index
int index
Definition: gx_internal_plugins.h:705
gx_system::JsonParser
Definition: gx_json.h:112
gx_engine::paradesc::step
float step
Definition: gx_internal_plugins.h:710
gx_engine::paradesc::has_caption
bool has_caption
Definition: gx_internal_plugins.h:713
gx_engine::paradesc::~paradesc
~paradesc()
Definition: ladspaplugin.cpp:1441
gx_engine::LV2Features::getInstance
static LV2Features & getInstance()
Definition: gx_internal_plugins.h:686
gx_print_error
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
UI_FORM_STACK
#define UI_FORM_STACK
Definition: gx_plugin.h:60
gx_system::JsonParser::begin_array
@ begin_array
Definition: gx_json.h:126
LADSPA_Data
float LADSPA_Data
Definition: ladspa.h:84
gx_engine::LadspaLoader::end
pluginarray::iterator end()
Definition: gx_internal_plugins.h:772
PluginDef::description
const char * description
Definition: gx_plugin.h:191
gx_engine::LadspaLoader::~LadspaLoader
~LadspaLoader()
Definition: ladspaplugin.cpp:1383
UiBuilder::closeBox
void(* closeBox)()
Definition: gx_plugin.h:77
LADSPA_IS_PORT_INPUT
#define LADSPA_IS_PORT_INPUT(x)
Definition: ladspa.h:168
gx_system::JsonParser::read_kv
bool read_kv(const char *key, float &v)
Definition: gx_json.cpp:511
gx_engine::tp_enum
@ tp_enum
Definition: gx_internal_plugins.h:704
gx_system::JsonWriter::begin_array
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
gx_engine::paradesc::readJSON
void readJSON(gx_system::JsonParser &jp)
Definition: ladspaplugin.cpp:183
gx_system::JsonParser::end_array
@ end_array
Definition: gx_json.h:127
_LADSPA_Descriptor::cleanup
void(* cleanup)(LADSPA_Handle Instance)
Definition: ladspa.h:558
value_pair::value_id
const char * value_id
Definition: gx_plugin.h:118
gx_engine::is_lv2
@ is_lv2
Definition: gx_internal_plugins.h:722
gx_engine::tp_scale
@ tp_scale
Definition: gx_internal_plugins.h:704
_LADSPA_Descriptor::deactivate
void(* deactivate)(LADSPA_Handle Instance)
Definition: ladspa.h:549
gx_system::JsonParser::end_object
@ end_object
Definition: gx_json.h:125
gx_engine::paradesc::tp
widget_type tp
Definition: gx_internal_plugins.h:711
gx_engine::plugdesc::master_idx
int master_idx
Definition: gx_internal_plugins.h:735
gx_engine::tp_scale_log
@ tp_scale_log
Definition: gx_internal_plugins.h:704
PluginDef::flags
int flags
Definition: gx_plugin.h:185
gx_engine::ParamMap
Definition: gx_parameter.h:515
ParamReg
Definition: gx_plugin.h:122
gx_system::CmdlineOptions
Definition: gx_system.h:381
gx_engine::Lv2Dsp::set_plugdesc
void set_plugdesc(const plugdesc *pd_)
Definition: ladspaplugin.cpp:1008
gx_engine::tp_none
@ tp_none
Definition: gx_internal_plugins.h:704
gx_system::JsonParser::value_number
@ value_number
Definition: gx_json.h:129
gx_engine::LadspaLoader::LadspaLoader
LadspaLoader(const gx_system::CmdlineOptions &options, ParamMap &param)
Definition: ladspaplugin.cpp:1368
gx_engine::LadspaLoader::find
pluginarray::iterator find(plugdesc *desc)
Definition: ladspaplugin.cpp:1418
gx_engine::paradesc::dflt
float dflt
Definition: gx_internal_plugins.h:707
UiBuilder
Definition: gx_plugin.h:63
gx_engine::Lv2Dsp::create
static Lv2Dsp * create(const plugdesc *plug, const LadspaLoader &loader)
Definition: ladspaplugin.cpp:875
ladspa_descriptor
const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index)
_LADSPA_Descriptor::Name
const char * Name
Definition: ladspa.h:393
LADSPA_Descriptor_Function
const typedef LADSPA_Descriptor *(* LADSPA_Descriptor_Function)(unsigned long Index)
Definition: ladspa.h:593
gx_engine::Lv2Dsp
Definition: ladspaplugin.cpp:837
PluginDef::activate_plugin
activatefunc activate_plugin
Definition: gx_plugin.h:201
start
CmdConnection::msg_type start
Definition: jsonrpc.cpp:257
gx_engine::LadspaLoader::create
PluginDef * create(unsigned int idx)
Definition: gx_internal_plugins.h:769
PLUGINDEF_VERSION
#define PLUGINDEF_VERSION
Definition: gx_plugin.h:181
gx_engine::LadspaLoader::set_plugins
void set_plugins(pluginarray &new_plugins)
Definition: ladspaplugin.cpp:1411
gx_engine::plugdesc::quirks
int quirks
Definition: gx_internal_plugins.h:732
gx_system::JsonParser::peek
token peek()
Definition: gx_json.h:139
gx_system::JsonWriter::write_key
void write_key(const char *p, bool nl=false)
Definition: gx_json.cpp:200
LADSPA_Handle
void * LADSPA_Handle
Definition: ladspa.h:363
gx_engine::plugdesc::stereo_to_mono
int stereo_to_mono
Definition: gx_internal_plugins.h:734
engine.h
UiBuilder::set_next_flags
void(* set_next_flags)(int flags)
Definition: gx_plugin.h:79
UiBuilder::create_master_slider
void(* create_master_slider)(const char *id, const char *label)
Definition: gx_plugin.h:84
gx_engine::LadspaLoader::load
bool load(pluginarray &p)
Definition: ladspaplugin.cpp:1394
gx_engine::paradesc::up
float up
Definition: gx_internal_plugins.h:709
UiBuilder::openHorizontalBox
void(* openHorizontalBox)(const char *label)
Definition: gx_plugin.h:71
_LADSPA_Descriptor::Label
const char * Label
Definition: ladspa.h:386
gx_engine::LadspaLoader::pluginarray
std::vector< plugdesc * > pluginarray
Definition: gx_internal_plugins.h:750
gx_engine::plugdesc::readJSON
void readJSON(gx_system::JsonParser &jp)
Definition: ladspaplugin.cpp:237
UiBuilder::openHorizontalhideBox
void(* openHorizontalhideBox)(const char *label)
Definition: gx_plugin.h:72
gx_system::JsonWriter::end_array
void end_array(bool nl=false)
Definition: gx_json.cpp:192
gx_engine::tp_toggle
@ tp_toggle
Definition: gx_internal_plugins.h:704
gx_engine::paradesc::low
float low
Definition: gx_internal_plugins.h:708
gx_engine::need_activate
@ need_activate
Definition: gx_internal_plugins.h:722
gx_engine::paradesc::name
std::string name
Definition: gx_internal_plugins.h:706
_LADSPA_Descriptor::UniqueID
unsigned long UniqueID
Definition: ladspa.h:379
gx_engine::paradesc::writeJSON
void writeJSON(gx_system::JsonWriter &jw)
Definition: ladspaplugin.cpp:212
LADSPA_IS_PORT_AUDIO
#define LADSPA_IS_PORT_AUDIO(x)
Definition: ladspa.h:171
_LADSPA_Descriptor
Definition: ladspa.h:373
gx_engine::LadspaDsp::set_plugdesc
void set_plugdesc(const plugdesc *pd_)
Definition: ladspaplugin.cpp:339
UI_LABEL_INVERSE
#define UI_LABEL_INVERSE
Definition: gx_plugin.h:45
gx_engine::tp_display
@ tp_display
Definition: gx_internal_plugins.h:704
gx_engine::Parameter
Definition: gx_parameter.h:106
_LADSPA_Descriptor::activate
void(* activate)(LADSPA_Handle Instance)
Definition: ladspa.h:489
ladspa.h
UiBuilder::create_switch
void(* create_switch)(const char *sw_type, const char *id, const char *label)
Definition: gx_plugin.h:94
gx_engine::plugdesc::id_str
std::string id_str
Definition: gx_internal_plugins.h:738
value_pair::value_label
const char * value_label
Definition: gx_plugin.h:119
UiBuilder::create_selector
void(* create_selector)(const char *id, const char *label)
Definition: gx_plugin.h:95
gx_engine::plugdesc::path
std::string path
Definition: gx_internal_plugins.h:726
LADSPA_PORT_INPUT
#define LADSPA_PORT_INPUT
Definition: ladspa.h:155
UiBuilder::insertSpacer
void(* insertSpacer)()
Definition: gx_plugin.h:78
gx_engine::tp_int
@ tp_int
Definition: gx_internal_plugins.h:704