Guitarix
ladspaback.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 <lrdf.h>
20 #include <ladspa.h>
21 #include <dlfcn.h>
22 
23 #include "engine.h"
24 
25 using Glib::ustring;
30 
31 namespace ladspa {
32 
33 //#define HARD_RT_ONLY
34 
35 static const unsigned long blacklist[] = {
36  4069, 4070, // ladspa_guitarix
37  1912, // jamincont (crashes on unload?)
38  //1044, 1045, 1046, 1047, // sine
39 };
40 
41 static bool lib_is_blacklisted(const std::string& name) {
42  static const char *blacklist[] = {
43  "dssi-vst.so",
44  };
45  for (unsigned int i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); i++) {
46  if (name == blacklist[i]) {
47  return true;
48  }
49  }
50  return false;
51 }
52 
53 static const unsigned long quirklist_no_cleanup[] = { 1912, 0 };
54 static const unsigned long quirklist_activate[] = { 1890, 1891, 1893, 1894, 1892, 1903, 1904, 0 };
55 static const struct {
56  int flag;
57  const unsigned long *ids;
58 } quirk_list[] = {
59  {1, quirklist_no_cleanup},
60  {2, quirklist_activate},
61  {0, 0}
62 };
63 
64 #define unknown_category "External"
65 
66 static const char *cat_subst[][2] = {
67  {"Reverbs", "Reverb"},
68  {"Filters", "Tone Control"},
69  {"EQs", "Tone Control"},
70  {"Compressors", "Guitar Effects"},
71  {"Utilities", "Misc"},
72  {"Delays", "Echo / Delay"},
73  {"Phasers", "Modulation"},
74  {"Chorus", "Modulation"},
75  {"Flangers", "Modulation"},
76  {"Modulators", "Modulation"},
77  {"Distortions", "Distortion"},
78  {"Waveshapers", "Distortion"},
79  {"Amplifiers", "Distortion"},
80  // added for LV2
81  {"Filter", "Tone Control"},
82  {"Distortion", "Distortion"},
83  {"Delay", "Echo / Delay"},
84  {"Modulator", "Modulation"},
85  {"Utility", "Misc"},
86  {"Compressor", "Guitar Effects"},
87  {0, 0}
88 };
89 
90 /****************************************************************
91  ** PluginDesc, PortDesc
92  */
93 
94 static inline bool float_eq(float v1, float v2) {
95  return std::abs(v1 - v2) <= 1e-5 * std::abs(v1);
96 }
97 
98 bool operator!=(const ChangeableValues& v1, const ChangeableValues& v2) {
99  if (v1.set_flags != v2.set_flags) {
100  return true;
101  }
102  if (v1.is_set(ChangeableValues::name_set) && v1.name != v2.name) {
103  return true;
104  }
105  if (v1.is_set(ChangeableValues::dflt_set) && !float_eq(v1.dflt, v2.dflt)) {
106  return true;
107  }
108  if (v1.is_set(ChangeableValues::low_set) && !float_eq(v1.low, v2.low)) {
109  return true;
110  }
111  if (v1.is_set(ChangeableValues::up_set) && !float_eq(v1.up, v2.up)) {
112  return true;
113  }
114  if (v1.is_set(ChangeableValues::tp_set) && v1.tp != v2.tp) {
115  return true;
116  }
117  if (v1.is_set(ChangeableValues::newrow_set) && v1.newrow != v2.newrow) {
118  return true;
119  }
120  if (v1.enumdict.size() != v2.enumdict.size()) {
121  return true;
122  }
123  for (std::map<int, ustring>::const_iterator i = v1.enumdict.begin(); i != v1.enumdict.end(); ++i) {
124  std::map<int, ustring>::const_iterator j = v2.enumdict.find(i->first);
125  if (j == v2.enumdict.end() || j->second != i->second) {
126  return true;
127  }
128  }
129  return false;
130 }
131 
132 
134  : name(), dflt(), low(), up(), tp(tp_scale), enumdict(), newrow(), set_flags(0) {
136  while (jp.peek() != gx_system::JsonParser::end_object) {
138  if (jp.read_kv("name", name) ||
139  jp.read_kv("dflt", dflt) ||
140  jp.read_kv("low", low) ||
141  jp.read_kv("up", up) ||
142  jp.read_kv("tp", tp) ||
143  jp.read_kv("newrow", newrow) ||
144  jp.read_kv("set_flags", set_flags)) {
145  } else if (jp.current_value() == "enumdict") {
147  while (jp.peek() != gx_system::JsonParser::end_object) {
149  int k = jp.current_value_int();
151  enumdict[k] = jp.current_value();
152  }
154  } else {
156  "ladspa::ChangeableValues", Glib::ustring::compose("unknown key: %1", jp.current_value()));
157  jp.skip_object();
158  }
159  }
161 }
162 
164  jw.begin_object();
165  jw.write_kv("name", name);
166  jw.write_kv("dflt", dflt);
167  jw.write_kv("low", low);
168  jw.write_kv("up", up);
169  jw.write_kv("tp", tp);
170  jw.write_kv("newrow", newrow);
171  jw.write_kv("set_flags", set_flags);
172  jw.write_key("enumdict");
173  jw.begin_object();
174  for (std::map<int, Glib::ustring>::iterator i = enumdict.begin(); i != enumdict.end(); ++i) {
175  jw.write_kv(gx_system::to_string(i->first).c_str(), i->second);
176  }
177  jw.end_object();
178  jw.end_object();
179 }
180 
182  switch (t) {
183  case tp_enabled: return low_set|up_set;
184  case tp_toggle: return low_set|up_set;
185  case tp_display: return dflt_set;
187  case tp_none: return dflt_set|low_set|up_set;
188  default: return 0;
189  }
190 }
191 
193  if ((set_flags & ~get_excl_flags(t)) || enumdict.size()) {
194  return true;
195  }
196  return false;
197 }
198 
199 PortDesc::PortDesc(int idx_, int pos_, bool is_output_, ustring name, const LADSPA_PortRangeHint& hint)
200  : idx(idx_), pos(pos_), is_output(is_output_), hint_desc(hint.HintDescriptor),
201  fake_low(false), fake_up(false), fake_dflt(false),
202  step(stp_normal), use_sr(false), has_sr(LADSPA_IS_HINT_SAMPLE_RATE(hint_desc)),
203  has_caption(true), factory(), user() {
204  factory.set_name(name);
205  set_range_default(hint, factory);
206  set_default_value(hint, factory);
207  set_tp_default(hint, factory);
208 }
209 
211  : idx(), pos(), is_output(), hint_desc(),
212  fake_low(false), fake_up(false), fake_dflt(false),
213  step(stp_normal), use_sr(false), has_sr(false),
214  has_caption(true), factory(), user() {
216  while (jp.peek() != gx_system::JsonParser::end_object) {
218  if (jp.read_kv("idx", idx) ||
219  jp.read_kv("pos", pos) ||
220  jp.read_kv("is_output", is_output) ||
221  jp.read_kv("hint_desc", hint_desc) ||
222  jp.read_kv("fake_low", fake_low) ||
223  jp.read_kv("fake_up", fake_up) ||
224  jp.read_kv("fake_dflt", fake_dflt) ||
225  jp.read_kv("step", step) ||
226  jp.read_kv("use_sr", use_sr) ||
227  jp.read_kv("has_sr", has_sr) ||
228  jp.read_kv("has_caption", has_caption)) {
229  } else if (jp.current_value() == "factory") {
231  } else if (jp.current_value() == "user") {
232  user = ChangeableValues(jp);
233  } else {
235  "ladspa::PortDesc", Glib::ustring::compose("unknown key: %1", jp.current_value()));
236  jp.skip_object();
237  }
238  }
240 }
241 
243  jw.begin_object();
244  jw.write_kv("idx", idx);
245  jw.write_kv("pos", pos);
246  jw.write_kv("is_output", is_output);
247  jw.write_kv("hint_desc", hint_desc);
248  jw.write_kv("fake_low", fake_low);
249  jw.write_kv("fake_up", fake_up);
250  jw.write_kv("fake_dflt", fake_dflt);
251  jw.write_kv("step", step);
252  jw.write_kv("use_sr", use_sr);
253  jw.write_kv("has_sr", has_sr);
254  jw.write_kv("has_caption", has_caption);
255  jw.write_key("factory"); factory.serializeJSON(jw);
256  jw.write_key("user"); user.serializeJSON(jw);
257  jw.end_object();
258 }
259 
264  store.set_dflt(0);
266  store.set_dflt(1);
268  store.set_dflt(100);
270  store.set_dflt(440);
272  store.set_dflt(get_low());
274  store.set_dflt(get_up());
275  } else {
276  float low = get_low();
277  float up = get_up();
281  if (low > 0) {
283  store.set_dflt(exp(log(low)*0.75 + log(up)*0.25));
285  store.set_dflt(exp(log(low)*0.5 + log(up)*0.5));
287  store.set_dflt(exp(log(low)*0.25 + log(up)*0.75));
288  }
289  } else {
291  }
292  } else {
294  store.set_dflt(low * 0.75 + up * 0.25);
296  store.set_dflt(low * 0.5 + up * 0.5);
298  store.set_dflt(low * 0.25 + up * 0.75);
299  }
300  }
301  }
302 }
303 
306  store.set_low(0);
307  store.set_up(1);
308  } else {
310  store.set_low(h.LowerBound);
311  } else {
313  }
315  store.set_up(h.UpperBound);
316  } else {
318  }
319  }
320 }
321 
323  step = stp_normal;
324  use_sr = false;
326  has_caption = true;
328 }
329 
330 void PortDesc::set_low(float v) {
331  if (!fake_low && float_eq(v, factory.get_low())) {
333  } else {
334  user.set_low(v);
335  }
336 }
337 
338 void PortDesc::set_up(float v) {
339  if (!fake_up && float_eq(v, factory.get_up())) {
341  } else {
342  user.set_up(v);
343  }
344 }
345 
346 void PortDesc::set_dflt(float v) {
347  if (!fake_dflt && float_eq(v, factory.get_dflt())) {
349  } else {
350  user.set_dflt(v);
351  }
352 }
353 
355  if (v == factory.get_tp()) {
357  } else {
358  user.set_tp(v);
359  }
360 }
361 
362 void PortDesc::set_newrow(bool v) {
363  if (v == factory.get_newrow()) {
365  } else {
366  user.set_newrow(v);
367  }
368 }
369 
370 ustring PortDesc::get_enum(int idx) {
371  std::map<int, ustring>::iterator i;
372  i = user.find_enum(idx);
373  if (i != user.enum_end()) {
374  return i->second;
375  }
376  i = factory.find_enum(idx);
377  if (i != factory.enum_end()) {
378  return i->second;
379  }
380  return "";
381 }
382 
383 bool PortDesc::check_changed(const PortDesc& vp) const {
384  if (pos != vp.pos) {
385  return true;
386  }
387  if (fake_low != vp.fake_low) {
388  return true;
389  }
390  if (fake_up != vp.fake_up) {
391  return true;
392  }
393  if (fake_dflt != vp.fake_dflt) {
394  return true;
395  }
396  if (step != vp.step) {
397  return true;
398  }
399  if (use_sr != vp.use_sr) {
400  return true;
401  }
402  if (has_sr != vp.has_sr) {
403  return true;
404  }
405  if (has_caption != vp.has_caption) {
406  return true;
407  }
408  if (factory != vp.factory) {
409  return true;
410  }
411  if (user != vp.user) {
412  return true;
413  }
414  return false;
415 }
416 
418  return !has_caption || step != stp_normal || use_sr || user.has_settings(get_tp());
419 }
420 
421 void PortDesc::fixup(bool newrow) {
423  f.set_newrow(newrow);
427  f.set_up(1.0);
428  f.set_low(1.0/1000.0);
429  f.set_dflt(sqrt(f.get_low()*f.get_up()));
430  fake_dflt = true;
431  } else if (f.get_dflt() <= 0) {
432  f.set_dflt(1.0);
433  fake_dflt = true;
434  f.set_low(f.get_dflt()/100.0);
435  f.set_up(f.get_dflt()*100.0);
436  } else {
437  f.set_low(f.get_dflt()/100.0);
438  f.set_up(f.get_dflt()*100.0);
439  }
440  fake_low = fake_up = true;
441  } else if (!f.is_set(ChangeableValues::low_set)) {
443  f.set_low(f.get_up()/1000.0);
444  f.set_dflt(f.get_low());
445  fake_dflt = true;
446  } else {
447  if (f.get_dflt() >= f.get_up()) {
448  f.set_dflt(f.get_up());
449  f.set_low(f.get_up() / 1000.0);
450  } else {
451  f.set_low(f.get_dflt());
452  }
453  }
454  fake_low = true;
455  } else if (!f.is_set(ChangeableValues::up_set)) {
456  if (f.get_low() == 0) {
457  f.set_low(1e-1);
458  fake_low = true;
459  }
461  f.set_up(f.get_low() * 1000.0);
462  f.set_dflt(f.get_low());
463  fake_dflt = true;
464  } else {
465  if (f.get_dflt() <= f.get_low()) {
466  f.set_dflt(f.get_low());
467  f.set_up(f.get_low() * 1000.0);
468  } else {
469  f.set_up(f.get_dflt());
470  }
471  }
472  fake_up = true;
473  } else if (f.get_low() <= 0) {
474  f.set_low(1e-7);
475  fake_low = true;
476  }
477  } else {
480  f.set_low(-1000);
481  f.set_up(1000);
482  f.set_dflt(0);
483  fake_dflt = true;
484  } else {
485  f.set_low(f.get_dflt() - 100);
486  f.set_up(f.get_dflt() + 100);
487  }
488  fake_low = fake_up = true;
489  } else if (!f.is_set(ChangeableValues::low_set)) {
491  f.set_low(f.get_up() - 1000);
492  f.set_dflt(f.get_low());
493  fake_dflt = true;
494  } else {
495  if (f.get_dflt() >= f.get_up()) {
496  f.set_dflt(f.get_up());
497  f.set_low(f.get_up() - 1000);
498  } else {
499  f.set_low(f.get_dflt());
500  }
501  }
502  fake_low = true;
503  } else if (!f.is_set(ChangeableValues::up_set)) {
505  f.set_up(f.get_low() + 1000);
506  f.set_dflt(f.get_low());
507  fake_dflt = true;
508  } else {
509  if (f.get_dflt() <= f.get_low()) {
510  f.set_dflt(f.get_low());
511  f.set_up(f.get_low() + 1000);
512  } else {
513  f.set_up(f.get_dflt());
514  }
515  }
516  fake_up = true;
517  }
518  }
520  fake_dflt = true;
521  f.set_dflt(f.get_low());
522  }
523  if (f.get_tp() == tp_enum) {
524  for (int k = int(f.get_low()); k < int(f.get_up()+1); k++) {
525  if (!f.has_enumkey(k)) {
527  }
528  }
529  }
530 }
531 
533  if (get_tp() == tp_enabled || get_tp() == tp_toggle || get_tp() == tp_enum || get_tp() == tp_int) {
534  return 1.0;
535  }
536  float up = get_up();
537  float low = get_low();
538  if (get_tp() == tp_scale_log) {
539  if (step == stp_coarse) {
540  return pow(up/low, 1.0/50);
541  }
542  if (step == stp_normal) {
543  return pow(up/low, 1.0/100);
544  }
545  if (step == stp_fine) {
546  return pow(up/low, 1.0/500);
547  }
548  assert(false);
549  return 1.0;
550  } else {
551  float s = 1.0;
552  if (step == stp_coarse) {
553  s = (up - low) / 30.0;
554  }
555  if (step == stp_normal) {
556  s = (up - low) / 300.0;
557  }
558  if (step == stp_fine) {
559  s = (up - low) / 3000.0;
560  }
561  if (has_sr && !use_sr) {
562  s *= SR;
563  }
564  return pow(10.0, round(log10(s)));
565  }
566 }
567 
569  if (is_output) {
571  store.set_tp(tp_display_toggle);
572  } else if (get_name() == "latency") {
573  store.set_tp(tp_none);
574  } else {
575  store.set_tp(tp_display);
576  }
577  } else if (LADSPA_IS_HINT_TOGGLED(h.HintDescriptor)) {
578  store.set_tp(tp_toggle);
580  store.set_tp(tp_scale_log);
581  } else if (LADSPA_IS_HINT_INTEGER(h.HintDescriptor)) {
582  store.set_tp(tp_int);
583  } else {
584  store.set_tp(tp_scale);
585  }
586 }
587 
588 void PortDesc::set_default(float value, ustring label) {
590  factory.set_dflt(value);
591  }
592 }
593 
595  float dflt = get_dflt();
596  float low = get_low();
597  float up = get_up();
598  if (has_sr && !use_sr) {
600  dflt *= SR;
601  }
603  low *= SR;
604  }
606  up *= SR;
607  }
608  }
609  jw.begin_array();
610  jw.write(idx);
611  jw.begin_array(); jw.write(step); jw.end_array();
613  jw.write(user.get_name());
614  } else {
615  jw.write("");
616  }
617  jw.write(use_sr);
618  jw.write(dflt);
619  jw.write(low);
620  jw.write(up);
621  jw.write(calc_step());
622  jw.write(get_tp());
623  jw.write(get_newrow());
624  jw.write(has_caption);
625  jw.begin_array();
626  if (get_tp() == tp_enum) {
627  int iup = int(round(up));
628  for (int i = int(round(low)); i < iup+1; ++i) {
629  jw.write(get_enum(i));
630  }
631  }
632  jw.end_array();
633  jw.end_array(true);
634 }
635 
636 void PortDesc::set_state(JsonParser& jp, int version) {
637  jp.next(JsonParser::begin_array);
638  jp.next(JsonParser::value_number);
639  step = static_cast<step_mode>(jp.current_value_int());
640  jp.next(JsonParser::end_array);
641  jp.next(JsonParser::value_string);
642  if (!jp.current_value().empty()) {
644  }
645  jp.next(JsonParser::value_number);
646  use_sr = jp.current_value_int();
647  jp.next(JsonParser::value_number);
648  float dflt = jp.current_value_float();
649  jp.next(JsonParser::value_number);
650  float low = jp.current_value_float();
651  jp.next(JsonParser::value_number);
652  float up = jp.current_value_float();
653  jp.next(JsonParser::value_number);
654  jp.current_value_float(); // step value, ignored
655  jp.next(JsonParser::value_number);
657  if (tp != factory.get_tp()) {
658  user.set_tp(tp);
659  }
660  if (has_sr && !use_sr) {
661  dflt /= SR;
662  low /= SR;
663  up /= SR;
664  }
665  if (!float_eq(dflt, factory.get_dflt())) {
666  user.set_dflt(dflt);
667  }
668  if (!float_eq(low, factory.get_low())) {
669  user.set_low(low);
670  }
671  if (!float_eq(up, factory.get_up())) {
672  user.set_up(up);
673  }
674  jp.next(JsonParser::value_number);
675  bool b = bool(jp.current_value_int());
676  if (b != factory.get_newrow()) {
677  user.set_newrow(b);
678  }
679  jp.next(JsonParser::value_number);
680  b = bool(jp.current_value_int());
681  has_caption = b;
682  jp.next(JsonParser::begin_array);
683  int s = int(low);
684  while (jp.peek() != JsonParser::end_array) {
685  jp.next(JsonParser::value_string);
686  std::map<int, ustring>::iterator it = factory.find_enum(s);
687  if (it != factory.enum_end() && jp.current_value() != it->second) {
689  }
690  s += 1;
691  }
692  jp.next(JsonParser::end_array);
693 }
694 
695 PluginDesc::PluginDesc(const LADSPA_Descriptor& desc, int tp_, std::vector<PortDesc*>& ctrl_ports_, const std::string path_, int index_)
696  : UniqueID(desc.UniqueID), Label(desc.Label), Name(desc.Name), shortname(desc.Name), Maker(desc.Maker),
697  MasterIdx(-1), MasterLabel(), tp(tp_), ctrl_ports(ctrl_ports_), path(path_), index(index_),
698  category(unknown_category), deduced_category(unknown_category), quirks(), quirks_default(), is_lv2(false),
699  ladspa_category(), active(false), active_set(false), has_settings(false), add_wet_dry(0), stereo_to_mono(0), old(0) {
700  quirks = quirks_default = quirks_get();
701 }
702 
703 PluginDesc::PluginDesc(LilvWorld *world, const LilvPlugin* plugin, int tp_, std::vector<PortDesc*>& ctrl_ports_)
704  : UniqueID(0), Label(), Name(), shortname(), Maker(),
705  MasterIdx(-1), MasterLabel(), tp(tp_), ctrl_ports(ctrl_ports_),
706  path(lilv_node_as_string(lilv_plugin_get_uri(plugin))), index(0),
707  category(unknown_category), deduced_category(unknown_category), quirks(), quirks_default(), is_lv2(true),
708  ladspa_category(), active(false), active_set(false), has_settings(false), add_wet_dry(0), stereo_to_mono(0), old(0) {
709  LilvNode* nd = lilv_plugin_get_name(plugin);
710  Glib::ustring s = lilv_node_as_string(nd);
711  lilv_node_free(nd);
712  Label = s;
713  Name = s;
714  shortname = s;
715  nd = lilv_plugin_get_author_name(plugin);
716  if (!nd) {
717  nd = lilv_plugin_get_project(plugin);
718  }
719  if (nd) {
720  Maker = lilv_node_as_string(nd);
721  } else {
722  Maker = "";
723  }
724  lilv_node_free(nd);
725  path = lilv_node_as_string(lilv_plugin_get_uri(plugin));
726  const LilvPluginClass* cls = lilv_plugin_get_class(plugin);
727  if (cls) {
728  std::vector<Glib::ustring> cats;
729  const LilvPluginClasses* pclasses = lilv_world_get_plugin_classes(world);
730  while (true) {
731  const LilvNode *pn = lilv_plugin_class_get_parent_uri(cls);
732  if (!pn) {
733  break;
734  }
735  const LilvPluginClass* pcls = lilv_plugin_classes_get_by_uri(pclasses, pn);
736  if (!pcls) {
737  break;
738  }
739  cats.insert(cats.begin(), lilv_node_as_string(lilv_plugin_class_get_label(cls)));
740  cls = pcls;
741  }
742  set_category(cats);
743  }
744 }
745 
746 PluginDesc::~PluginDesc() {
747  delete old;
748  for (std::vector<PortDesc*>::iterator i = ctrl_ports.begin(); i != ctrl_ports.end(); ++i) {
749  delete *i;
750  }
751 }
752 
754  UniqueID(),
755  Label(),
756  Name(),
757  shortname(),
758  Maker(),
759  MasterIdx(),
760  MasterLabel(),
761  tp(),
762  ctrl_ports(),
763  path(),
764  index(),
765  category(),
766  deduced_category(),
767  quirks(),
768  quirks_default(),
769  is_lv2(),
770  ladspa_category(),
771  active(),
772  active_set(),
773  has_settings(),
774  add_wet_dry(),
775  stereo_to_mono(),
776  old(0) {
778  while (jp.peek() != gx_system::JsonParser::end_object) {
780  if (jp.read_kv("UniqueID", UniqueID) ||
781  jp.read_kv("Label", Label) ||
782  jp.read_kv("Name", Name) ||
783  jp.read_kv("shortname", shortname) ||
784  jp.read_kv("Maker", Maker) ||
785  jp.read_kv("MasterIdx", MasterIdx) ||
786  jp.read_kv("MasterLabel", MasterLabel) ||
787  jp.read_kv("tp", tp) ||
788  jp.read_kv("path", path) ||
789  jp.read_kv("index", index) ||
790  jp.read_kv("category", category) ||
791  jp.read_kv("deduced_category", deduced_category) ||
792  jp.read_kv("quirks", quirks) ||
793  jp.read_kv("quirks_default", quirks_default) ||
794  jp.read_kv("is_lv2", is_lv2) ||
795  jp.read_kv("ladspa_category", ladspa_category) ||
796  jp.read_kv("active", active) ||
797  jp.read_kv("active_set", active_set) ||
798  jp.read_kv("has_settings", has_settings) ||
799  jp.read_kv("add_wet_dry", add_wet_dry) ||
800  jp.read_kv("stereo_to_mono", stereo_to_mono)) {
801  } else if (jp.current_value() == "old") {
802  old = new PluginDesc(jp);
803  } else if (jp.current_value() == "ctrl_ports") {
805  while (jp.peek() != gx_system::JsonParser::end_array) {
806  ctrl_ports.push_back(new PortDesc(jp));
807  }
809  } else {
811  "ladspa::PluginDesc", Glib::ustring::compose("unknown key: %1", jp.current_value()));
812  jp.skip_object();
813  }
814  }
816 }
817 
818 void PluginDesc::serializeJSON(gx_system::JsonWriter& jw) {
819  jw.begin_object();
820  jw.write_kv("UniqueID", static_cast<unsigned int>(UniqueID));
821  jw.write_kv("Label", Label);
822  jw.write_kv("Name", Name);
823  jw.write_kv("shortname", shortname);
824  jw.write_kv("Maker", Maker);
825  jw.write_kv("MasterIdx", MasterIdx);
826  jw.write_kv("MasterLabel", MasterLabel);
827  jw.write_kv("tp", tp);
828  jw.write_kv("path", path);
829  jw.write_kv("index", index);
830  jw.write_kv("category", category);
831  jw.write_kv("deduced_category", deduced_category);
832  jw.write_kv("quirks", quirks);
833  jw.write_kv("quirks_default", quirks_default);
834  jw.write_kv("is_lv2", is_lv2);
835  jw.write_kv("ladspa_category", ladspa_category);
836  jw.write_kv("active", active);
837  jw.write_kv("active_set", active_set);
838  jw.write_kv("has_settings", has_settings);
839  jw.write_kv("add_wet_dry", add_wet_dry);
840  jw.write_kv("stereo_to_mono", stereo_to_mono);
841  if (old) {
842  jw.write_key("old");
843  old->serializeJSON(jw);
844  }
845  jw.write_key("ctrl_ports");
846  jw.begin_array();
847  for (std::vector<PortDesc*>::iterator i = ctrl_ports.begin(); i != ctrl_ports.end(); ++i) {
848  (*i)->serializeJSON(jw);
849  }
850  jw.end_array();
851  jw.end_object();
852 }
853 
855  int flag = 0;
856  for (int i = 0; quirk_list[i].flag; i++) {
857  for (int j = 0; quirk_list[i].ids[j]; j++) {
858  if (UniqueID == quirk_list[i].ids[j]) {
859  flag |= quirk_list[i].flag;
860  }
861  }
862  }
863  return flag;
864 }
865 
866 bool cmp_ctrl_ports(const PortDesc *a, const PortDesc *b) {
867  return a->pos < b->pos;
868 }
869 
871  shortname = Name;
872  MasterIdx = -1;
873  MasterLabel = "";
874  add_wet_dry = 0;
877  has_settings = false;
878  std::sort(ctrl_ports.begin(), ctrl_ports.end(), cmp_ctrl_ports);
879  for (std::vector<PortDesc*>::iterator p = ctrl_ports.begin(); p != ctrl_ports.end(); ++p) {
880  (*p)->reset();
881  }
882 }
883 
885  assert(ctrl_ports.size() == 0);
886  for (std::vector<PortDesc*>::iterator i = p->ctrl_ports.begin(); i != p->ctrl_ports.end(); ++i) {
887  ctrl_ports.push_back(new PortDesc(**i));
888  }
889 }
890 
891 //static
892 void LadspaPluginList::add_plugin(const LADSPA_Descriptor& desc, pluginmap& d, const std::string& path, int index) {
893  for (unsigned int j = 0; j < sizeof(blacklist)/sizeof(blacklist[0]); j++) {
894  if (desc.UniqueID == blacklist[j]) {
895  return;
896  }
897  }
898 #ifdef HARD_RT_ONLY
900  return;
901  }
902 #endif
903  int n_in = 0;
904  int n_out = 0;
905  std::vector<PortDesc*> ctrl_ports;
906  int pos = 0;
907  for (unsigned int n = 0; n < desc.PortCount; n++) {
909  if (LADSPA_IS_PORT_AUDIO(pd)) {
910  if (LADSPA_IS_PORT_INPUT(pd)) {
911  n_in += 1;
912  } else {
913  n_out += 1;
914  }
915  } else {
916  ctrl_ports.push_back(new PortDesc(n, pos, LADSPA_IS_PORT_OUTPUT(pd), desc.PortNames[n], desc.PortRangeHints[n]));
917  pos += 1;
918  }
919  }
920  int tp;
921  if (n_in == 1 && n_out == 1) {
922  tp = 0;
923  } else if (n_in == 2 && n_out == 2) {
924  tp = 1;
925  } else {
926  for (std::vector<PortDesc*>::iterator i = ctrl_ports.begin(); i != ctrl_ports.end(); ++i) {
927  delete *i;
928  }
929  return;
930  }
931  d[make_key(desc.UniqueID)] = new PluginDesc(desc, tp, ctrl_ports, path, index);
932 }
933 
934 //static
935 void LadspaPluginList::load_defs(const std::string& path, pluginmap& d) {
936  void *handle;
937  handle = dlopen(path.c_str(), RTLD_LOCAL|RTLD_NOW);
938  if (!handle) {
940  "ladspalist",
941  ustring::compose(_("Cannot open plugin: %1\n"), dlerror()));
942  return;
943  }
944  LADSPA_Descriptor_Function ladspa_descriptor = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor");
945  const char *dlsym_error = dlerror();
946  if (dlsym_error) {
947  gx_print_warning("ladspalist", dlsym_error);
948  dlclose(handle);
949  handle = 0;
950  return;
951  }
952  int i = 0;
953  while (true) {
954  const LADSPA_Descriptor *desc = ladspa_descriptor(i);
955  if (!desc) {
956  break;
957  }
958  add_plugin(*desc, d, path, i);
959  i += 1;
960  }
961  dlclose(handle);
962 }
963 
965  if (!old) {
966  return false;
967  }
968  if (UniqueID != old->UniqueID) {
969  return true;
970  }
971  if (Label != old->Label) {
972  return true;
973  }
974  if (Name != old->Name) {
975  return true;
976  }
977  if (shortname != old->shortname) {
978  return true;
979  }
980  if (Maker != old->Maker) {
981  return true;
982  }
983  if (MasterIdx != old->MasterIdx) {
984  return true;
985  }
986  if (MasterIdx > -1 && MasterLabel != old->MasterLabel) {
987  return true;
988  }
989  if (add_wet_dry != old->add_wet_dry) {
990  return true;
991  }
993  return true;
994  }
995  if (tp != old->tp) {
996  return true;
997  }
998  if (path != old->path) {
999  return true;
1000  }
1001  if (index != old->index) {
1002  return true;
1003  }
1004  if (category != old->category) {
1005  return true;
1006  }
1008  return true;
1009  }
1010  if (quirks != old->quirks) {
1011  return true;
1012  }
1013  if (quirks_default != old->quirks_default) {
1014  return true;
1015  }
1017  return true;
1018  }
1019  for (unsigned int i = 0; i < ctrl_ports.size(); ++i) {
1020  if (ctrl_ports[i]->check_changed(*old->ctrl_ports[i])) {
1021  return true;
1022  }
1023  }
1024  return false;
1025 }
1026 
1028  if (shortname != Name) {
1029  return true;
1030  }
1031  if (category != deduced_category) {
1032  return true;
1033  }
1034  if (quirks != quirks_default) {
1035  return true;
1036  }
1037  if (MasterIdx != -1) {
1038  return true;
1039  }
1040  for (int i = 0; i < static_cast<int>(ctrl_ports.size()); ++i) {
1041  if (i != ctrl_ports[i]->get_pos()) {
1042  return true;
1043  }
1044  if (ctrl_ports[i]->has_settings()) {
1045  return true;
1046  }
1047  }
1048  return false;
1049 }
1050 
1053 }
1054 
1056  if (v == active) {
1057  return 0;
1058  }
1059  active = v;
1060  if (v == active_set) {
1061  return -1;
1062  }
1063  return 1;
1064 }
1065 
1067  if (v) {
1068  add_wet_dry = 1;
1069  } else {
1070  add_wet_dry = 0;
1071  }
1072 }
1073 
1075  if (v) {
1076  stereo_to_mono = 1;
1077  } else {
1078  stereo_to_mono = 0;
1079  }
1080 }
1081 
1083  int i = 0;
1084  for (unsigned int n = 0; n < ctrl_ports.size(); ++n) {
1085  bool newrow = false;
1086  if (ctrl_ports[n]->get_tp() != tp_none) {
1087  newrow = (i % 6 == 0 && i != 0);
1088  i += 1;
1089  }
1090  ctrl_ports[n]->fixup(newrow);
1091  }
1092 }
1093 
1094 void PluginDesc::set_category(const std::vector<ustring>& s) {
1095  bool found = false;
1096  ustring t = "";
1097  for (std::vector<ustring>::const_iterator i = s.begin(); i != s.end(); ++i) {
1098  if (!t.empty()) {
1099  t += "/";
1100  }
1101  t += *i;
1102  if (!found) {
1103  for (const char *(*p)[2] = cat_subst; (*p)[0]; ++p) {
1104  if (*i == (*p)[0]) {
1105  category = deduced_category = (*p)[1];
1106  found = true;
1107  break;
1108  }
1109  }
1110  }
1111  }
1112  ladspa_category = t;
1113 }
1114 
1115 void PluginDesc::set_default(int idx, float value, const ustring& label) {
1116  for (std::vector<PortDesc*>::iterator p = ctrl_ports.begin(); p != ctrl_ports.end(); ++p) {
1117  if ((*p)->idx == idx) {
1118  (*p)->set_default(value, label);
1119  return;
1120  }
1121  }
1122 }
1123 
1125  ustring s = shortname;
1126  if (s == Name) {
1127  s = "";
1128  }
1129  int idx = -1;
1130  ustring sm = "";
1131  if (MasterIdx >= 0) {
1132  for (std::vector<PortDesc*>::iterator p = ctrl_ports.begin(); p != ctrl_ports.end(); ++p) {
1133  ++idx;
1134  if ((*p)->pos == MasterIdx) {
1135  sm = MasterLabel;
1136  if (sm == (*p)->get_name()) {
1137  sm = "";
1138  }
1139  break;
1140  }
1141  }
1142  }
1143  jw.begin_array();
1144  jw.write(3); // version
1145  jw.write(s);
1146  jw.write(category);
1147  jw.write(idx);
1148  jw.write(sm);
1149  jw.write(quirks | (is_lv2 ? gx_engine::is_lv2 : 0));
1150  jw.write(add_wet_dry);
1151  jw.write(stereo_to_mono);
1152  jw.begin_array(true);
1153  for (std::vector<PortDesc*>::iterator p = ctrl_ports.begin(); p != ctrl_ports.end(); ++p) {
1154  (*p)->output(jw);
1155  }
1156  jw.end_array(true);
1157  jw.end_array(true);
1158 }
1159 
1161  jw.begin_array();
1162  jw.write(path);
1163  if (is_lv2) {
1164  jw.write(-1);
1165  } else {
1166  jw.write(index);
1167  }
1168  jw.write(uint(UniqueID));
1169  jw.write(Label);
1170  jw.end_array(true);
1171 }
1172 
1173 void PluginDesc::set_state(const ustring& fname) {
1174  ifstream is(fname.c_str());
1175  if (is.fail()) {
1176  gx_print_error("ladspalist", ustring::compose(_("can't open %1"), fname));
1177  return;
1178  }
1179  try {
1180  JsonParser jp(&is);
1181  jp.next(JsonParser::begin_array);
1182  jp.next(JsonParser::value_number);
1183  int version = jp.current_value_int();
1184  jp.next(JsonParser::value_string);
1185  shortname = jp.current_value();
1186  if (shortname.empty()) {
1187  shortname = Name;
1188  }
1189  jp.next(JsonParser::value_string);
1190  category = jp.current_value();
1191  jp.next(JsonParser::value_number);
1193  jp.next(JsonParser::value_string);
1194  MasterLabel = jp.current_value();
1195  jp.next(JsonParser::value_number);
1196  quirks = jp.current_value_int();
1197  if (quirks & gx_engine::is_lv2) {
1199  is_lv2 = true;
1200  }
1201  jp.next(JsonParser::value_number);
1203  if (jp.peek() == JsonParser::value_number) {
1204  jp.next(JsonParser::value_number);
1206  }
1207  std::vector<PortDesc*> ports;
1208  jp.next(JsonParser::begin_array);
1209  int n = 0;
1210  int m_idx = MasterIdx;
1211  while (jp.peek() != JsonParser::end_array) {
1212  jp.next(JsonParser::begin_array);
1213  jp.next(JsonParser::value_number);
1214  int idx = jp.current_value_int();
1215  for (std::vector<PortDesc*>::iterator p = ctrl_ports.begin(); p != ctrl_ports.end(); ++p) {
1216  if ((*p)->idx == idx) {
1217  if (m_idx == n) {
1218  MasterIdx = (*p)->pos;
1219  }
1220  (*p)->set_state(jp, version);
1221  ports.push_back((*p));
1222  break;
1223  }
1224  }
1225  n++;
1226  jp.next(JsonParser::end_array);
1227  }
1228  jp.next(JsonParser::end_array);
1229  if (ctrl_ports.size() == ports.size()) ctrl_ports = ports;
1230  //assert(ctrl_ports.size() == ports.size());
1231  //ctrl_ports = ports;
1232  jp.next(JsonParser::end_array);
1233  jp.next(JsonParser::end_token);
1234  jp.close();
1235  } catch(JsonException& e) {
1237  "ladspalist",
1238  ustring::compose(_("error parsing LADSPA plugin config file %1: %2"), fname, e.what()));
1239  return;
1240  }
1241  is.close();
1243 }
1244 
1246  old = new PluginDesc(*this);
1247  old->ctrl_ports.clear();
1248  old->copy_ports(this);
1249 }
1250 
1251 
1252 /****************************************************************
1253  ** class LadspaPluginList
1254  */
1255 
1256 static struct {
1257  unsigned long from, to;
1258 } ranges_1_based[] = {
1259  // swh
1260  {1181, 1440},
1261  {1605, 1605},
1262  {1881, 1922},
1263  // blop
1264  {1641, 1680},
1265  {2021, 2038},
1266 };
1267 
1269  : std::vector<PluginDesc*>(),
1270  world(lilv_world_new()),
1271  lv2_plugins(),
1272  lv2_AudioPort(lilv_new_uri(world, LV2_CORE__AudioPort)),
1273  lv2_ControlPort(lilv_new_uri(world, LV2_CORE__ControlPort)),
1274  lv2_InputPort(lilv_new_uri(world, LV2_CORE__InputPort)),
1275  lv2_OutputPort(lilv_new_uri(world, LV2_CORE__OutputPort)),
1276  lv2_connectionOptional(lilv_new_uri(world, LV2_CORE__connectionOptional)) {
1277  LilvNode* false_val = lilv_new_bool(world, false);
1278  lilv_world_set_option(world,LILV_OPTION_DYN_MANIFEST, false_val);
1279  lilv_world_load_all(world);
1280  lv2_plugins = lilv_world_get_all_plugins(world);
1281  lilv_node_free(false_val);
1282 }
1283 
1284 static bool in_1_based_range(unsigned long uid) {
1285  for (unsigned int i = 0; i < sizeof(ranges_1_based)/sizeof(ranges_1_based[0]); ++i) {
1286  if (uid >= ranges_1_based[i].from && uid <= ranges_1_based[i].to) {
1287  return true;
1288  }
1289  }
1290  return false;
1291 }
1292 
1293 //static
1294 void LadspaPluginList::set_instances(const char *uri, pluginmap& d, std::vector<ustring>& label,
1295  std::vector<unsigned long>& not_found, std::set<unsigned long>& seen) {
1296  lrdf_uris *uris = lrdf_get_instances(uri);
1297  if (uris) {
1298  for (unsigned int i = 0; i < uris->count; ++i) {
1299  const char *u = uris->items[i];
1300  unsigned long uid = lrdf_get_uid(u);
1301  std::string uid_key = make_key(uid);
1302  if (d.find(uid_key) == d.end()) {
1303  not_found.push_back(uid);
1304  seen.insert(uid);
1305  continue;
1306  }
1307  if (seen.find(uid) == seen.end()) {
1308  PluginDesc *pd = d[uid_key];
1309  pd->set_category(label);
1310  for (unsigned int n = 0; n < pd->ctrl_ports.size(); n++) {
1311  PortDesc *p = pd->ctrl_ports[n];
1312  lrdf_defaults *sval = lrdf_get_scale_values(uid, p->idx);
1313  if (sval) {
1314  for (unsigned int nn = 0; nn < sval[0].count; nn++) {
1315  lrdf_portvalue& t = sval[0].items[nn];
1316  p->factory.set_enumvalue(t.value, t.label);
1317  }
1318  lrdf_free_setting_values(sval);
1319  if (LADSPA_IS_HINT_INTEGER(p->hint_desc)) {
1320  p->factory.set_tp(tp_enum);
1321  }
1322  }
1323  }
1324  uri = lrdf_get_default_uri(uid);
1325  if (uri) {
1326  lrdf_defaults *sval = lrdf_get_setting_values(uri);
1327  if (sval) {
1328  for (unsigned int nn = 0; nn < sval[0].count; nn++) {
1329  lrdf_portvalue& t = sval[0].items[nn];
1330  int idx = t.pid;
1331  if (in_1_based_range(uid)) {
1332  idx -= 1;
1333  }
1334  pd->set_default(idx, t.value, t.label);
1335  }
1336  lrdf_free_setting_values(sval);
1337  }
1338  }
1339  }
1340  seen.insert(uid);
1341  }
1342  lrdf_free_uris(uris);
1343  }
1344 }
1345 
1346 //static
1347 void LadspaPluginList::descend(const char *uri, pluginmap& d,
1348  std::vector<unsigned long>& not_found,
1349  std::set<unsigned long>& seen,
1350  std::vector<ustring>& base) {
1351  lrdf_uris *uris = lrdf_get_subclasses(uri);
1352  if (uris) {
1353  for (unsigned int i = 0; i < uris->count; ++i) {
1354  const char *u = uris->items[i];
1355  base.push_back(lrdf_get_label(u));
1356  set_instances(u, d, base, not_found, seen);
1357  descend(u, d, not_found, seen, base);
1358  base.pop_back();
1359  }
1360  lrdf_free_uris(uris);
1361  }
1362 }
1363 
1364 void LadspaPluginList::get_preset_values(const char* port_symbol,
1365  void* user_data,
1366  const void* value,
1367  uint32_t size,
1368  uint32_t type) {
1369  LV2Preset* pdata = (LV2Preset*)user_data;
1370  for (unsigned int i=0;i< pdata->num_ports;i++) {
1371  const LilvPort* port = lilv_plugin_get_port_by_index(pdata->plugin, i);
1372  const char* sym = lilv_node_as_string(lilv_port_get_symbol(pdata->plugin,port));
1373  if (strcmp(sym, port_symbol) ==0) {
1374  float fvalue = *(const float*)value;
1375  Glib::ustring port_id = pdata->sname ;
1376  pdata->cline += " \"lv2_";
1377  pdata->cline += port_id ;
1378  pdata->cline += "." ;
1380  pdata->cline += "\": " ;
1381  pdata->cline += gx_system::to_string(fvalue);
1382  pdata->cline += "\n";
1383 
1384  }
1385  }
1386  }
1387 
1388 void LadspaPluginList::set_preset_values(Glib::ustring port_symbol,
1389  LV2Preset* pdata,
1390  Glib::ustring value) {
1391  for (unsigned int i=0;i< pdata->num_ports;i++) {
1392  const LilvPort* port = lilv_plugin_get_port_by_index(pdata->plugin, i);
1393  Glib::ustring sym = lilv_node_as_string(lilv_port_get_symbol(pdata->plugin,port));
1394  if (sym.compare(port_symbol) ==0) {
1395  Glib::ustring port_id = pdata->sname ;
1396  pdata->cline += " \"lv2_";
1397  pdata->cline += port_id ;
1398  pdata->cline += "." ;
1400  pdata->cline += "\": " ;
1401  pdata->cline += value;
1402  pdata->cline += "\n";
1403  break;
1404  }
1405  }
1406  }
1407 
1408 void LadspaPluginList::get_presets(LV2Preset *pdata) {
1409  pdata->cline ="[\"gx_plugin_version\", 1,\n";
1410  LilvNodes* presets = lilv_plugin_get_related(pdata->plugin,
1411  lilv_new_uri(world,LV2_PRESETS__Preset));
1412  LILV_FOREACH(nodes, i, presets) {
1413  const LilvNode* preset = lilv_nodes_get(presets, i);
1414  lilv_world_load_resource(world, preset);
1415  LilvNodes* labels = lilv_world_find_nodes(
1416  world, preset, lilv_new_uri(world, LILV_NS_RDFS "label"), NULL);
1417  if (labels) {
1418  const LilvNode* label = lilv_nodes_get_first(labels);
1419  if (label) {
1420  Glib::ustring set = lilv_node_as_string(label);
1421  pdata->has_preset = true;
1422  LilvState* state = lilv_state_new_from_world(world, &gx_engine::LV2Features::getInstance().gx_urid_map, preset);
1423  pdata->cline +=" \"" + set + "\"" + " {\n";
1424 
1425  Glib::ustring stt = lilv_state_to_string(world,&gx_engine::LV2Features::getInstance().gx_urid_map,&gx_engine::LV2Features::getInstance().gx_urid_unmap,state,"<>",NULL);
1426  std::istringstream stream(stt);
1427  std::string st;
1428  Glib::ustring symbol = "";
1429  Glib::ustring value = "";
1430  while (std::getline(stream, st)) {
1431  std::size_t found = st.find("lv2:symbol");
1432  if(found !=Glib::ustring::npos) {
1433  std::size_t found1 = st.find("\"",found)+1;
1434  std::size_t found2 = st.find("\"",found1);
1435  if(found2 !=Glib::ustring::npos) {
1436  symbol = st.substr(found1, (found2-found1));
1437  } else {
1438  continue;
1439  }
1440  }
1441  found = st.find("pset:value");
1442  if(found !=Glib::ustring::npos) {
1443  std::size_t found1 = st.find(" ",found)+1;
1444  if(found1 !=Glib::ustring::npos) {
1445  value = st.substr(found1);
1446  set_preset_values(symbol,pdata,value);
1447  } else {
1448  continue;
1449  }
1450  }
1451  }
1452  //lilv_state_emit_port_values(state, get_preset_values, pdata);
1453  lilv_state_free(state);
1454  pdata->cline += " },\n";
1455  }
1456  }
1457  lilv_nodes_free(labels);
1458  }
1459  lilv_nodes_free(presets);
1460 }
1461 
1462 bool LadspaPluginList::feature_is_supported(const char* uri)
1463 {
1464  if (!strcmp(uri, "http://lv2plug.in/ns/lv2core#isLive")) {
1465  return true;
1466  }
1467  for (const LV2_Feature*const* f = gx_engine::LV2Features::getInstance().gx_features; *f; ++f) {
1468  if (!strcmp(uri, (*f)->URI)) {
1469  //fprintf(stderr, "Feature %s is supported\n", uri);
1470  return true;
1471  }
1472  }
1473  return false;
1474 }
1475 void LadspaPluginList::add_plugin(const LilvPlugin* plugin, pluginmap& d, gx_system::CmdlineOptions& options) {
1476 
1477  // check for requested features
1478  LilvNodes* requests = lilv_plugin_get_required_features(plugin);
1479  LILV_FOREACH(nodes, f, requests) {
1480  const char* uri = lilv_node_as_uri(lilv_nodes_get(requests, f));
1481  if (!feature_is_supported(uri)) {
1482  //fprintf(stderr, "Plugin %s \n", lilv_node_as_string(lilv_plugin_get_uri(plugin)));
1483  //fprintf(stderr, "Feature %s is not supported\n", uri);
1484  lilv_nodes_free(requests);
1485  return;
1486  }
1487  }
1488  lilv_nodes_free(requests);
1489 
1490  int n_in = 0;
1491  int n_out = 0;
1492  unsigned int ena_port = 0;
1493  bool ena = false;
1494  std::vector<PortDesc*> ctrl_ports;
1495  int pos = 0;
1496  unsigned int num_ports = lilv_plugin_get_num_ports(plugin);
1497 
1498  LilvNode* is_ena = lilv_new_uri(world, LV2_CORE__enabled);
1499  const LilvPort* enabled_port = lilv_plugin_get_port_by_designation(plugin, lv2_ControlPort, is_ena);
1500  if (enabled_port) {
1501  ena_port = lilv_port_get_index(plugin, enabled_port);
1502  ena = true;
1503  }
1504  lilv_node_free(is_ena);
1505 
1506  for (unsigned int n = 0; n < num_ports; n++) {
1507  const LilvPort* port = lilv_plugin_get_port_by_index(plugin, n);
1508  if (lilv_port_is_a(plugin, port, lv2_AudioPort)) {
1509  if (lilv_port_is_a(plugin, port, lv2_InputPort)) {
1510  n_in += 1;
1511  } else {
1512  n_out += 1;
1513  }
1514  } else if (lilv_port_is_a(plugin, port, lv2_ControlPort)) {
1515  LADSPA_PortRangeHint hint;
1516  hint.HintDescriptor = 0;
1517  hint.LowerBound = hint.UpperBound = 0;
1518  LilvNode *pdflt, *pmin, *pmax;
1519  lilv_port_get_range(plugin, port, &pdflt, &pmin, &pmax);
1520  if (pmin) {
1521  hint.LowerBound = lilv_node_as_float(pmin);
1523  lilv_node_free(pmin);
1524  }
1525  if (pmax) {
1526  hint.UpperBound = lilv_node_as_float(pmax);
1528  lilv_node_free(pmax);
1529  }
1530  LilvNode* nm = lilv_port_get_name(plugin, port);
1531  PortDesc *pdesc = new PortDesc(n, pos, lilv_port_is_a(plugin, port, lv2_OutputPort), lilv_node_as_string(nm), hint);
1532  lilv_node_free(nm);
1533  if (pdflt) {
1534  pdesc->factory.set_dflt(lilv_node_as_float(pdflt));
1535  lilv_node_free(pdflt);
1536  }
1537  LilvNode* is_int = lilv_new_uri(world, LV2_CORE__integer);
1538  if (lilv_port_has_property(plugin, port, is_int)) {
1539  pdesc->factory.set_tp(tp_int);
1540  }
1541  lilv_node_free(is_int);
1542  LilvNode* is_tog = lilv_new_uri(world, LV2_CORE__toggled);
1543  if (lilv_port_has_property(plugin, port, is_tog)) {
1544  pdesc->factory.set_tp(tp_toggle);
1545  }
1546  lilv_node_free(is_tog);
1547  LilvScalePoints* sp = lilv_port_get_scale_points(plugin, port);
1548  int num_sp = lilv_scale_points_size(sp);
1549  if (num_sp > 0) {
1550  for (LilvIter* it = lilv_scale_points_begin(sp);
1551  !lilv_scale_points_is_end(sp, it);
1552  it = lilv_scale_points_next(sp, it)) {
1553  const LilvScalePoint* p = lilv_scale_points_get(sp, it);
1554  pdesc->factory.set_enumvalue(
1555  lilv_node_as_float(lilv_scale_point_get_value(p)),
1556  lilv_node_as_string(lilv_scale_point_get_label(p)));
1557  }
1558  pdesc->factory.set_tp(tp_enum);
1559  }
1560  lilv_scale_points_free(sp);
1561 
1562  if (ena) {
1563  if (n == ena_port) {
1564  pdesc->factory.set_tp(tp_enabled);
1565  }
1566  }
1567 
1568  ctrl_ports.push_back(pdesc);
1569  pos += 1;
1570  } else {
1571  if (!lilv_port_has_property(plugin, port, lv2_connectionOptional)) {
1572  n_out = 0; // fail
1573  break;
1574  }
1575  }
1576  }
1577  int tp;
1578  if (n_in == 1 && n_out == 1) {
1579  tp = 0;
1580  } else if (n_in == 2 && n_out == 2) {
1581  tp = 1;
1582  } else {
1583  for (std::vector<PortDesc*>::iterator i = ctrl_ports.begin(); i != ctrl_ports.end(); ++i) {
1584  delete *i;
1585  }
1586  return;
1587  }
1588 
1589  // check if plugin instantiate
1590  // LilvInstance* instance = lilv_plugin_instantiate(plugin, 48000, 0);
1591  // if (!instance) {
1592  // return;
1593  // }
1594  // lilv_instance_free(instance);
1595 
1596  PluginDesc* p = d[lilv_node_as_string(lilv_plugin_get_uri(plugin))] = new PluginDesc(world, plugin, tp, ctrl_ports);
1597  pdata.has_preset = false;
1598  if (options.reload_lv2_presets) {
1599  if (p->path.size() != 0) {
1601  pdata.ctrl_ports = ctrl_ports;
1602  pdata.num_ports = num_ports;
1603  pdata.plugin = const_cast<LilvPlugin*>(plugin);
1604  get_presets(&pdata);
1605  }
1606  }
1607 
1608 }
1609 
1610 void LadspaPluginList::lv2_load(pluginmap& d, gx_system::CmdlineOptions& options) {
1611  for (LilvIter* it = lilv_plugins_begin(lv2_plugins);
1612  !lilv_plugins_is_end(lv2_plugins, it);
1613  it = lilv_plugins_next(lv2_plugins, it)) {
1614  add_plugin(lilv_plugins_get(lv2_plugins, it), d, options);
1615  if (options.reload_lv2_presets) {
1616  if (pdata.has_preset && pdata.cline.size() != 0) {
1617  pdata.cline.replace(pdata.cline.end()-2,pdata.cline.end()-1,"");
1618  pdata.cline += "]\n";
1619  std::string pfile = options.get_lv2_preset_dir();
1620  pfile += "lv2_";
1621  pfile += pdata.sname;
1622  ofstream os (pfile.c_str());
1623  os << pdata.cline;
1624  os.close();
1625  }
1626  pdata.has_preset = false;
1627  }
1628  }
1629  options.reload_lv2_presets = false;
1630 }
1631 
1632 static bool cmp_plugins(const PluginDesc *a, const PluginDesc *b) {
1633  return ustring(a->Name) < ustring(b->Name);
1634 }
1635 
1636 void LadspaPluginList::load(gx_system::CmdlineOptions& options, std::vector<std::string>& old_not_found) {
1637  gx_system::PathList pl("LADSPA_PATH");
1638  if (!pl.size()) {
1639  pl.add("/usr/lib/ladspa");
1640  pl.add("/usr/local/lib/ladspa");
1641  pl.add("/usr/lib64/ladspa");
1642  pl.add("/usr/local/lib64/ladspa");
1643  }
1644  pluginmap d;
1645  for (gx_system::PathList::iterator it = pl.begin(); it != pl.end(); ++it) {
1646  Glib::RefPtr<Gio::File> file = *it;
1647  if (!file->query_exists()) {
1648  continue;
1649  }
1650  Glib::RefPtr<Gio::FileEnumerator> child_enumeration =
1651  file->enumerate_children(G_FILE_ATTRIBUTE_STANDARD_NAME
1652  "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
1653  "," G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
1654  Glib::RefPtr<Gio::FileInfo> file_info;
1655 
1656  while ((file_info = child_enumeration->next_file())) {
1657  if (file_info->get_attribute_string(G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE) == "application/x-sharedlib") {
1658  std::string nm = file_info->get_attribute_byte_string(G_FILE_ATTRIBUTE_STANDARD_NAME);
1659  if (lib_is_blacklisted(nm)) {
1660  continue;
1661  }
1662  //printf("opening %s/%s\n", file->get_path().c_str(), nm.c_str());
1663  load_defs(Glib::build_filename(file->get_path(), nm), d);
1664  }
1665  }
1666  }
1667  gx_system::PathList rpl("LADSPA_RDF_PATH");
1668  if (!rpl.size()) {
1669  rpl.add("/usr/share/ladspa/rdf");
1670  rpl.add("/usr/local/share/ladspa/rdf");
1671  }
1672  lrdf_init();
1673  for (gx_system::PathList::iterator it = rpl.begin(); it != rpl.end(); ++it) {
1674  Glib::RefPtr<Gio::File> file = *it;
1675  if (!file->query_exists()) {
1676  continue;
1677  }
1678  Glib::RefPtr<Gio::FileEnumerator> child_enumeration =
1679  file->enumerate_children(G_FILE_ATTRIBUTE_STANDARD_NAME
1680  "," G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
1681  "," G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
1682  Glib::RefPtr<Gio::FileInfo> file_info;
1683 
1684  while ((file_info = child_enumeration->next_file())) {
1685  //if not f.endswith((".rdf",".rdfs")):
1686  if (file_info->get_attribute_string(G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE) == "application/rdf+xml") {
1687  std::string nm = file_info->get_attribute_byte_string(G_FILE_ATTRIBUTE_STANDARD_NAME);
1688  if (lib_is_blacklisted(nm)) {
1689  continue;
1690  }
1691  lrdf_read_file(("file://"+Glib::build_filename(file->get_path(), nm)).c_str());
1692  }
1693  }
1694  }
1695  std::vector<unsigned long> not_found;
1696  std::set<unsigned long> seen;
1697  std::vector<ustring> base;
1698  locale_t loc = newlocale(LC_ALL, "C", 0);
1699  uselocale(loc);
1700  descend(LADSPA_BASE "Plugin", d, not_found, seen, base);
1701  uselocale(LC_GLOBAL_LOCALE);
1702  freelocale(loc);
1703  lrdf_cleanup();
1704 
1705  lv2_load(d, options);
1706 
1707  ifstream is(options.get_ladspa_config_filename().c_str());
1708  if (!is.fail()) {
1709  try {
1710  JsonParser jp(&is);
1711  jp.next(JsonParser::begin_array);
1712  while (jp.peek() == JsonParser::begin_array) {
1713  jp.next(JsonParser::begin_array);
1714  jp.next(JsonParser::value_string); // path
1715  std::string key = jp.current_value();
1716  jp.next(JsonParser::value_number); // index
1717  int idx = jp.current_value_int();
1718  jp.next(JsonParser::value_number); // UniqueID
1719  if (idx >= 0) {
1720  unsigned long uid = jp.current_value_uint();
1721  key = make_key(uid);
1722  }
1723  if (d.find(key) == d.end()) {
1724  old_not_found.push_back(key);
1725  } else {
1726  d[key]->set_active(true);
1727  d[key]->active_set = true;
1728  }
1729  jp.next(JsonParser::value_string); // Label
1730  jp.next(JsonParser::end_array);
1731  }
1732  jp.close();
1733  } catch(JsonException& e) {
1735  "ladspalist", ustring::compose(
1736  _("error loading ladspa plugin selection data from file %1"),
1737  options.get_ladspa_config_filename()));
1738  }
1739  is.close();
1740  }
1741  for (pluginmap::iterator v = d.begin(); v != d.end(); ++v) {
1742  v->second->fixup();
1743  std::string s;
1744  if (v->second->is_lv2) {
1745  s = gx_system::encode_filename(v->second->path) + ".js";
1746  } else {
1748  }
1749  std::string fname = options.get_plugin_filepath(s);
1750  if (access(fname.c_str(), F_OK) != 0) {
1751  fname = options.get_factory_filepath(s);
1752  if (access(fname.c_str(), F_OK) != 0) {
1753  fname = "";
1754  }
1755  }
1756  if (!fname.empty()) {
1757  v->second->set_state(fname);
1758  }
1759  }
1760  for (pluginmap::iterator i = d.begin(); i != d.end(); ++i) {
1761  push_back(i->second);
1762  }
1763  std::sort(begin(), end(), cmp_plugins);
1764 }
1765 
1767  std::string fname = options.get_ladspa_config_filename();
1768  std::string tfname = fname + ".tmp";
1769  ofstream tfile(tfname.c_str());
1770  JsonWriter jw(&tfile);
1771  jw.begin_array(true);
1772  for (std::vector<PluginDesc*>::iterator p = begin(); p != end(); ++p) {
1773  if ((*p)->active) {
1774  (*p)->output_entry(jw);
1775  }
1776  }
1777  jw.end_array(true);
1778  jw.close();
1779  tfile.close();
1780  std::vector<std::pair<std::string,std::string> > fl;
1781  for (std::vector<PluginDesc*>::iterator p = begin(); p != end(); ++p) {
1782  std::string sname = ((*p)->is_lv2 ?
1783  gx_system::encode_filename((*p)->path) + ".js" :
1785  std::string cname = options.get_plugin_filepath(sname);
1786  if ((*p)->active || (*p)->has_settings) {
1787  std::string tcname = cname + ".tmp";
1788  ofstream tcfile(tcname.c_str());
1789  JsonWriter jw2(&tcfile);
1790  (*p)->output(jw2);
1791  jw2.close();
1792  tcfile.close();
1793  fl.push_back(std::pair<std::string,std::string>(tcname, cname));
1794  } else {
1795  fl.push_back(std::pair<std::string,std::string>("", cname));
1796  }
1797  }
1798  if (rename(tfname.c_str(), fname.c_str()) != 0) {
1799  char buf[100];
1800  strerror_r(errno, buf, sizeof(buf));
1802  "ladspalist",ustring::compose(_("error renaming LADSPA config file '%1': %2"), fname, buf));
1803  return;
1804  }
1805  for (std::vector<std::pair<std::string,std::string> >::iterator i = fl.begin(); i != fl.end(); ++i) {
1806  if (i->first.empty()) {
1807  unlink(i->second.c_str());
1808  } else {
1809  if (rename(i->first.c_str(), i->second.c_str()) != 0) {
1810  char buf[100];
1811  strerror_r(errno, buf, sizeof(buf));
1813  "ladspalist",
1814  ustring::compose("error renaming %1 to %2: %3\n", i->first, i->second, buf));
1815  }
1816  }
1817  }
1818 }
1819 
1820 
1823  while (jp.peek() != gx_system::JsonParser::end_array) {
1824  push_back(new ladspa::PluginDesc(jp));
1825  }
1827 }
1828 
1830  jw.begin_array();
1831  for (iterator i = begin(); i != end(); ++i) {
1832  (*i)->serializeJSON(jw);
1833  }
1834  jw.end_array();
1835 }
1836 
1838  for (iterator i = begin(); i != end(); ++i) {
1839  delete *i;
1840  }
1841  lilv_node_free(lv2_AudioPort);
1842  lilv_node_free(lv2_ControlPort);
1843  lilv_node_free(lv2_InputPort);
1844  lilv_node_free(lv2_OutputPort);
1845  lilv_node_free(lv2_connectionOptional);
1846  lilv_world_free(world);
1847 }
1848 
1849 } // namespace ladspa
ladspa::LadspaPluginList::save
void save(gx_system::CmdlineOptions &options)
Definition: ladspaback.cpp:1766
ladspa::PortDesc::has_settings
bool has_settings()
Definition: ladspaback.cpp:417
gx_system::JsonParser::value_key
@ value_key
Definition: gx_json.h:130
ladspa::PortDesc::SR
static const int SR
Definition: ladspaback.h:94
ladspa::PluginDesc::Name
Glib::ustring Name
Definition: ladspaback.h:140
ladspa::PortDesc::set_up
void set_up(float v)
Definition: ladspaback.cpp:338
gx_system::JsonParser::begin_object
@ begin_object
Definition: gx_json.h:124
ladspa::PortDesc::fixup
void fixup(bool newrow)
Definition: ladspaback.cpp:421
ladspa::ChangeableValues::serializeJSON
void serializeJSON(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:163
ladspa::PluginDesc::output
void output(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:1124
ladspa::PluginDesc::shortname
Glib::ustring shortname
Definition: ladspaback.h:141
gx_system::JsonWriter::begin_object
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
ladspa::PluginDesc::set_category
void set_category(const std::vector< Glib::ustring > &s)
Definition: ladspaback.cpp:1094
gx_system::encode_filename
std::string encode_filename(const std::string &s)
Definition: gx_system.cpp:1013
ladspa::PluginDesc::deduced_category
Glib::ustring deduced_category
Definition: ladspaback.h:150
gx_system::JsonParser::value_string
@ value_string
Definition: gx_json.h:128
ladspa::PluginDesc::active_set
bool active_set
Definition: ladspaback.h:156
ladspa::PluginDesc::is_lv2
bool is_lv2
Definition: ladspaback.h:153
gx_engine::LV2Features
Definition: gx_internal_plugins.h:666
ladspa::PluginDesc::reset
void reset()
Definition: ladspaback.cpp:870
ladspa::LadspaPluginList::~LadspaPluginList
~LadspaPluginList()
Definition: ladspaback.cpp:1837
ladspa::tp_display_toggle
@ tp_display_toggle
Definition: ladspaback.h:30
gx_system::PathList::size
size_t size()
Definition: gx_system.h:300
ladspa::ChangeableValues::get_up
float get_up()
Definition: ladspaback.h:62
ladspa::stp_normal
@ stp_normal
Definition: ladspaback.h:74
LADSPA_IS_HINT_INTEGER
#define LADSPA_IS_HINT_INTEGER(x)
Definition: ladspa.h:315
LV2_CORE__enabled
#define LV2_CORE__enabled
Definition: engine.h:79
LADSPA_IS_HINT_DEFAULT_1
#define LADSPA_IS_HINT_DEFAULT_1(x)
Definition: ladspa.h:330
ladspa::PortDesc::set_low
void set_low(float v)
Definition: ladspaback.cpp:330
ladspa::ChangeableValues::set_dflt
void set_dflt(float v)
Definition: ladspaback.h:54
ladspa::PortDesc
Definition: ladspaback.h:78
ladspa::PortDesc::fake_low
bool fake_low
Definition: ladspaback.h:85
ladspa::PortDesc::check_changed
bool check_changed(const PortDesc &vp) const
Definition: ladspaback.cpp:383
LADSPA_PortDescriptor
int LADSPA_PortDescriptor
Definition: ladspa.h:152
ladspa::PortDesc::step
step_mode step
Definition: ladspaback.h:88
ladspa::ChangeableValues::has_settings
bool has_settings(DisplayType tp) const
Definition: ladspaback.cpp:192
ladspa::ChangeableValues::newrow_set
@ newrow_set
Definition: ladspaback.h:33
_LADSPA_Descriptor::PortCount
unsigned long PortCount
Definition: ladspa.h:406
ladspa::PortDesc::get_enum
Glib::ustring get_enum(int idx)
Definition: ladspaback.cpp:370
ladspa::PortDesc::serializeJSON
void serializeJSON(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:242
ladspa::ChangeableValues::dflt_set
@ dflt_set
Definition: ladspaback.h:33
ladspa::PortDesc::set_default
void set_default(float value, Glib::ustring label)
Definition: ladspaback.cpp:588
ladspa::PortDesc::factory
ChangeableValues factory
Definition: ladspaback.h:92
ladspa::to
unsigned long to
Definition: ladspaback.cpp:1259
ladspa::PluginDesc::MasterLabel
Glib::ustring MasterLabel
Definition: ladspaback.h:144
gx_system::CmdlineOptions::get_plugin_filepath
std::string get_plugin_filepath(const std::string &basename) const
Definition: gx_system.h:466
ladspa::tp_toggle
@ tp_toggle
Definition: ladspaback.h:30
ladspa::tp_none
@ tp_none
Definition: ladspaback.h:30
gx_system::JsonParser::current_value
string current_value() const
Definition: gx_json.h:143
ladspa::PluginDesc::active
bool active
Definition: ladspaback.h:155
ladspa::PluginDesc::set_stereo_to_mono
void set_stereo_to_mono(bool v)
Definition: ladspaback.cpp:1074
gx_system::JsonWriter::write
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
ladspa::tp_int
@ tp_int
Definition: ladspaback.h:30
LADSPA_IS_HINT_TOGGLED
#define LADSPA_IS_HINT_TOGGLED(x)
Definition: ladspa.h:312
ladspa::LV2Preset::has_preset
bool has_preset
Definition: ladspaback.h:199
ladspa::ChangeableValues::set_newrow
void set_newrow(bool v)
Definition: ladspaback.h:58
ladspa::PortDesc::fake_dflt
bool fake_dflt
Definition: ladspaback.h:87
ladspa::ChangeableValues::up_set
@ up_set
Definition: ladspaback.h:33
ladspa::ChangeableValues::set_enumvalue
void set_enumvalue(int k, const Glib::ustring &v)
Definition: ladspaback.h:66
gx_system::CmdlineOptions::get_factory_filepath
std::string get_factory_filepath(const std::string &basename) const
Definition: gx_system.h:467
ladspa::PortDesc::output
void output(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:594
_LADSPA_PortRangeHint::UpperBound
LADSPA_Data UpperBound
Definition: ladspa.h:350
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::flag
int flag
Definition: ladspaback.cpp:56
_LADSPA_PortRangeHint::HintDescriptor
LADSPA_PortRangeHintDescriptor HintDescriptor
Definition: ladspa.h:340
LADSPA_IS_HINT_DEFAULT_MIDDLE
#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x)
Definition: ladspa.h:322
ladspa::PortDesc::get_name
const Glib::ustring & get_name()
Definition: ladspaback.h:116
ladspa::PortDesc::user
ChangeableValues user
Definition: ladspaback.h:93
ladspa::ChangeableValues::set_low
void set_low(float v)
Definition: ladspaback.h:55
ladspa::PortDesc::use_sr
bool use_sr
Definition: ladspaback.h:89
LADSPA_IS_HINT_DEFAULT_LOW
#define LADSPA_IS_HINT_DEFAULT_LOW(x)
Definition: ladspa.h:320
ladspa::ChangeableValues::set_name
void set_name(const Glib::ustring &nm)
Definition: ladspaback.h:53
ladspa::PluginDesc::quirks_default
int quirks_default
Definition: ladspaback.h:152
ladspa::stp_fine
@ stp_fine
Definition: ladspaback.h:75
ladspa::PortDesc::get_low
float get_low()
Definition: ladspaback.h:112
PluginDesc
Definition: gx_main_window.cpp:2032
ladspa::PluginDesc::quirks_get
int quirks_get()
Definition: ladspaback.cpp:854
ladspa::PortDesc::has_sr
bool has_sr
Definition: ladspaback.h:90
gx_system::JsonException
Definition: gx_json.h:40
ladspa::PortDesc::get_tp
DisplayType get_tp()
Definition: ladspaback.h:111
gx_system::JsonParser::close
virtual void close()
Definition: gx_json.cpp:277
ladspa::PluginDesc
Definition: ladspaback.h:134
LADSPA_IS_HINT_DEFAULT_100
#define LADSPA_IS_HINT_DEFAULT_100(x)
Definition: ladspa.h:332
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
ladspa::PortDesc::is_output
bool is_output
Definition: ladspaback.h:83
unknown_category
#define unknown_category
Definition: ladspaback.cpp:64
ladspa::PortDesc::get_dflt
float get_dflt()
Definition: ladspaback.h:114
gx_system::JsonWriter::close
virtual void close()
Definition: gx_json.cpp:68
LADSPA_IS_HINT_SAMPLE_RATE
#define LADSPA_IS_HINT_SAMPLE_RATE(x)
Definition: ladspa.h:313
ladspa::PluginDesc::has_settings
bool has_settings
Definition: ladspaback.h:157
ladspa::PluginDesc::check_changed
bool check_changed()
Definition: ladspaback.cpp:964
ladspa::PluginDesc::fixup
void fixup()
Definition: ladspaback.cpp:1082
ladspa::ids
const unsigned long * ids
Definition: ladspaback.cpp:57
ladspa::PortDesc::reset
void reset()
Definition: ladspaback.cpp:322
ladspa::PortDesc::set_dflt
void set_dflt(float v)
Definition: ladspaback.cpp:346
ladspa::PluginDesc::tp
int tp
Definition: ladspaback.h:145
ladspa::PluginDesc::set_old
void set_old()
Definition: ladspaback.cpp:1245
ladspa::PluginDesc::add_wet_dry
int add_wet_dry
Definition: ladspaback.h:158
LADSPA_IS_HARD_RT_CAPABLE
#define LADSPA_IS_HARD_RT_CAPABLE(x)
Definition: ladspa.h:136
ladspa::ChangeableValues::ChangeableValues
ChangeableValues()
Definition: ladspaback.h:46
ladspa::PluginDesc::set_active
int set_active(bool v)
Definition: ladspaback.cpp:1055
gx_system::PathList::iterator
std::list< Glib::RefPtr< Gio::File > >::const_iterator iterator
Definition: gx_system.h:292
PluginDesc::PluginDesc
PluginDesc(const Glib::ustring &g, std::vector< PluginUI * > *p)
Definition: gx_main_window.cpp:2035
LADSPA_HINT_BOUNDED_ABOVE
#define LADSPA_HINT_BOUNDED_ABOVE
Definition: ladspa.h:216
gx_system::JsonParser::next
token next(token expect=no_token)
Definition: gx_json.cpp:496
ladspa::PluginDesc::category
Glib::ustring category
Definition: ladspaback.h:149
ladspa::PortDesc::set_range_default
void set_range_default(const LADSPA_PortRangeHint &h, ChangeableValues &store)
Definition: ladspaback.cpp:304
gx_engine::LadspaLoader::get_ladspa_filename
static std::string get_ladspa_filename(unsigned long uid)
Definition: gx_internal_plugins.h:777
ladspa
Definition: ladspaback.h:21
LADSPA_IS_PORT_OUTPUT
#define LADSPA_IS_PORT_OUTPUT(x)
Definition: ladspa.h:169
gx_engine
Definition: gx_convolver.h:33
LADSPA_IS_HINT_DEFAULT_MAXIMUM
#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x)
Definition: ladspa.h:326
ladspa::PluginDesc::path
std::string path
Definition: ladspaback.h:147
gx_system::JsonWriter::write_kv
void write_kv(const char *key, float v)
Definition: gx_json.h:81
ladspa::PortDesc::set_tp
void set_tp(DisplayType v)
Definition: ladspaback.cpp:354
ladspa::PortDesc::set_newrow
void set_newrow(bool v)
Definition: ladspaback.cpp:362
ladspa::PortDesc::fake_up
bool fake_up
Definition: ladspaback.h:86
gx_system::JsonWriter
Definition: gx_json.h:55
ladspa::ChangeableValues::get_low
float get_low()
Definition: ladspaback.h:61
_LADSPA_Descriptor::PortDescriptors
const LADSPA_PortDescriptor * PortDescriptors
Definition: ladspa.h:410
ladspa::PortDesc::pos
int pos
Definition: ladspaback.h:82
ladspa::tp_scale
@ tp_scale
Definition: ladspaback.h:30
ladspa::PluginDesc::UniqueID
unsigned long UniqueID
Definition: ladspaback.h:138
LADSPA_IS_HINT_LOGARITHMIC
#define LADSPA_IS_HINT_LOGARITHMIC(x)
Definition: ladspa.h:314
gx_system::PathList
Definition: gx_system.h:289
gx_system::JsonParser
Definition: gx_json.h:112
ladspa::ChangeableValues::get_excl_flags
int get_excl_flags(DisplayType tp) const
Definition: ladspaback.cpp:181
_LADSPA_PortRangeHint::LowerBound
LADSPA_Data LowerBound
Definition: ladspa.h:345
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
gx_system::JsonParser::begin_array
@ begin_array
Definition: gx_json.h:126
ladspa::PortDesc::set_default_value
void set_default_value(const LADSPA_PortRangeHint &h, ChangeableValues &store)
Definition: ladspaback.cpp:260
ladspa::PluginDesc::set_add_wet_dry_controller
void set_add_wet_dry_controller(bool v)
Definition: ladspaback.cpp:1066
ladspa::LadspaPluginList::writeJSON
void writeJSON(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:1829
LADSPA_IS_PORT_INPUT
#define LADSPA_IS_PORT_INPUT(x)
Definition: ladspa.h:168
ladspa::LadspaPluginList::readJSON
void readJSON(gx_system::JsonParser &jp)
Definition: ladspaback.cpp:1821
LADSPA_IS_HINT_DEFAULT_0
#define LADSPA_IS_HINT_DEFAULT_0(x)
Definition: ladspa.h:328
gx_system::JsonParser::read_kv
bool read_kv(const char *key, float &v)
Definition: gx_json.cpp:511
gx_system::JsonWriter::begin_array
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
ladspa::LV2Preset::sname
std::string sname
Definition: ladspaback.h:194
ladspa::LV2Preset::ctrl_ports
std::vector< PortDesc * > ctrl_ports
Definition: ladspaback.h:195
ladspa::ChangeableValues::name_set
@ name_set
Definition: ladspaback.h:33
gx_system::CmdlineOptions::reload_lv2_presets
bool reload_lv2_presets
Definition: gx_system.h:456
ladspa::ChangeableValues::get_dflt
float get_dflt()
Definition: ladspaback.h:60
_LADSPA_Descriptor::Properties
LADSPA_Properties Properties
Definition: ladspa.h:389
LADSPA_IS_HINT_HAS_DEFAULT
#define LADSPA_IS_HINT_HAS_DEFAULT(x)
Definition: ladspa.h:317
gx_system::JsonParser::end_array
@ end_array
Definition: gx_json.h:127
gx_engine::is_lv2
@ is_lv2
Definition: gx_internal_plugins.h:722
ladspa::LadspaPluginList::pdata
LV2Preset pdata
Definition: ladspaback.h:229
_LADSPA_PortRangeHint
Definition: ladspa.h:337
ladspa::ChangeableValues::get_tp
DisplayType get_tp()
Definition: ladspaback.h:63
_LADSPA_Descriptor::PortRangeHints
const LADSPA_PortRangeHint * PortRangeHints
Definition: ladspa.h:419
ladspa::PluginDesc::Maker
Glib::ustring Maker
Definition: ladspaback.h:142
ladspa::ChangeableValues::find_enum
std::map< int, Glib::ustring >::iterator find_enum(int k)
Definition: ladspaback.h:67
gx_system::JsonParser::end_object
@ end_object
Definition: gx_json.h:125
ladspa::PluginDesc::ladspa_category
std::string ladspa_category
Definition: ladspaback.h:154
ladspa::DisplayType
DisplayType
Definition: ladspaback.h:27
ladspa::PluginDesc::quirks
int quirks
Definition: ladspaback.h:151
ladspa::PortDesc::PortDesc
PortDesc(int idx_, int pos_, bool is_output_, Glib::ustring name, const LADSPA_PortRangeHint &hint)
ladspa::ChangeableValues::unset
void unset(int f)
Definition: ladspaback.h:52
ladspa::PluginDesc::index
int index
Definition: ladspaback.h:148
LADSPA_IS_HINT_BOUNDED_ABOVE
#define LADSPA_IS_HINT_BOUNDED_ABOVE(x)
Definition: ladspa.h:311
ladspa::LV2Preset::cline
std::string cline
Definition: ladspaback.h:198
ladspa::ChangeableValues::set_up
void set_up(float v)
Definition: ladspaback.h:56
ladspa::PortDesc::has_caption
bool has_caption
Definition: ladspaback.h:91
gx_system::CmdlineOptions
Definition: gx_system.h:381
ladspa::stp_coarse
@ stp_coarse
Definition: ladspaback.h:73
gx_system::JsonParser::current_value_uint
unsigned int current_value_uint()
Definition: gx_json.h:145
LADSPA_HINT_BOUNDED_BELOW
#define LADSPA_HINT_BOUNDED_BELOW
Definition: ladspa.h:208
ladspa::PluginDesc::set_state
void set_state(const Glib::ustring &fname)
Definition: ladspaback.cpp:1173
LADSPA_IS_HINT_DEFAULT_HIGH
#define LADSPA_IS_HINT_DEFAULT_HIGH(x)
Definition: ladspa.h:324
ladspa::tp_enum
@ tp_enum
Definition: ladspaback.h:30
ladspa::PluginDesc::check_has_settings
void check_has_settings()
Definition: ladspaback.cpp:1051
ladspa::PluginDesc::stereo_to_mono
int stereo_to_mono
Definition: ladspaback.h:159
ladspa::PluginDesc::MasterIdx
int MasterIdx
Definition: ladspaback.h:143
ladspa::ChangeableValues
Definition: ladspaback.h:31
LADSPA_IS_HINT_DEFAULT_MINIMUM
#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x)
Definition: ladspa.h:318
gx_system::JsonParser::current_value_int
int current_value_int()
Definition: gx_json.h:144
ladspa_descriptor
const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index)
ladspa::tp_scale_log
@ tp_scale_log
Definition: ladspaback.h:30
LADSPA_Descriptor_Function
const typedef LADSPA_Descriptor *(* LADSPA_Descriptor_Function)(unsigned long Index)
Definition: ladspa.h:593
ladspa::ChangeableValues::get_newrow
bool get_newrow()
Definition: ladspaback.h:64
gx_system::PathList::end
iterator end()
Definition: gx_system.h:302
ladspa::PluginDesc::ctrl_ports
std::vector< PortDesc * > ctrl_ports
Definition: ladspaback.h:146
ladspa::PortDesc::set_state
void set_state(gx_system::JsonParser &jp, int version)
Definition: ladspaback.cpp:636
gx_system::JsonParser::current_value_float
float current_value_float()
Definition: gx_json.h:146
ladspa::LadspaPluginList::LadspaPluginList
LadspaPluginList()
Definition: ladspaback.cpp:1268
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::step_mode
step_mode
Definition: ladspaback.h:72
ladspa::PluginDesc::Label
Glib::ustring Label
Definition: ladspaback.h:139
ladspa::operator!=
bool operator!=(const ChangeableValues &v1, const ChangeableValues &v2)
Definition: ladspaback.cpp:98
engine.h
gx_system::JsonParser::skip_object
void skip_object()
Definition: gx_json.cpp:611
end
CmdConnection::msg_type end
Definition: jsonrpc.cpp:258
ladspa::LV2Preset::num_ports
unsigned int num_ports
Definition: ladspaback.h:197
ladspa::ChangeableValues::set_tp
void set_tp(DisplayType v)
Definition: ladspaback.h:57
ladspa::ChangeableValues::is_set
bool is_set(int f) const
Definition: ladspaback.h:51
ladspa::ChangeableValues::tp_set
@ tp_set
Definition: ladspaback.h:33
ladspa::PortDesc::hint_desc
LADSPA_PortRangeHintDescriptor hint_desc
Definition: ladspaback.h:84
ladspa::PortDesc::get_newrow
bool get_newrow()
Definition: ladspaback.h:115
gx_system::CmdlineOptions::get_lv2_preset_dir
const std::string & get_lv2_preset_dir() const
Definition: gx_system.h:477
ladspa::PortDesc::set_tp_default
void set_tp_default(const LADSPA_PortRangeHint &h, ChangeableValues &store)
Definition: ladspaback.cpp:568
ladspa::ChangeableValues::get_name
const Glib::ustring & get_name()
Definition: ladspaback.h:59
gx_system::JsonWriter::end_array
void end_array(bool nl=false)
Definition: gx_json.cpp:192
ladspa::PluginDesc::output_entry
void output_entry(gx_system::JsonWriter &jw)
Definition: ladspaback.cpp:1160
gx_system::PathList::add
void add(const std::string &d)
Definition: gx_system.h:297
gx_system::PathList::begin
iterator begin()
Definition: gx_system.h:301
LADSPA_IS_HINT_BOUNDED_BELOW
#define LADSPA_IS_HINT_BOUNDED_BELOW(x)
Definition: ladspa.h:310
_LADSPA_Descriptor::UniqueID
unsigned long UniqueID
Definition: ladspa.h:379
ladspa::from
unsigned long from
Definition: ladspaback.cpp:1259
LADSPA_IS_PORT_AUDIO
#define LADSPA_IS_PORT_AUDIO(x)
Definition: ladspa.h:171
ladspa::PluginDesc::_i_check_has_settings
bool _i_check_has_settings()
Definition: ladspaback.cpp:1027
_LADSPA_Descriptor
Definition: ladspa.h:373
ladspa::cmp_ctrl_ports
bool cmp_ctrl_ports(const PortDesc *a, const PortDesc *b)
Definition: ladspaback.cpp:866
ladspa::PluginDesc::copy_ports
void copy_ports(PluginDesc *p)
Definition: ladspaback.cpp:884
ladspa::ChangeableValues::enum_end
std::map< int, Glib::ustring >::iterator enum_end()
Definition: ladspaback.h:69
ladspa::PluginDesc::set_default
void set_default(int idx, float value, const Glib::ustring &label)
Definition: ladspaback.cpp:1115
ladspa::LadspaPluginList::load
void load(gx_system::CmdlineOptions &options, std::vector< std::string > &old_not_found)
Definition: ladspaback.cpp:1636
ladspa.h
ladspa::PortDesc::calc_step
float calc_step()
Definition: ladspaback.cpp:532
_LADSPA_Descriptor::PortNames
const char *const * PortNames
Definition: ladspa.h:415
ladspa::ChangeableValues::low_set
@ low_set
Definition: ladspaback.h:33
gx_system::CmdlineOptions::get_ladspa_config_filename
std::string get_ladspa_config_filename() const
Definition: gx_system.h:481
ladspa::PortDesc::idx
int idx
Definition: ladspaback.h:81
ladspa::ChangeableValues::has_enumkey
bool has_enumkey(int k)
Definition: ladspaback.h:65
ladspa::tp_display
@ tp_display
Definition: ladspaback.h:30
ladspa::tp_enabled
@ tp_enabled
Definition: ladspaback.h:30
ladspa::PluginDesc::old
PluginDesc * old
Definition: ladspaback.h:160
ladspa::LV2Preset::plugin
LilvPlugin * plugin
Definition: ladspaback.h:196
LADSPA_IS_HINT_DEFAULT_440
#define LADSPA_IS_HINT_DEFAULT_440(x)
Definition: ladspa.h:334
ladspa::PortDesc::get_up
float get_up()
Definition: ladspaback.h:113