Guitarix
gx_pluginloader.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Hermann Meyer, James Warden, Andreas Degert, Pete Shorthose
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 <dirent.h>
21 
22 #include "engine.h"
23 
24 namespace gx_engine {
25 
26 /****************************************************************
27  ** class ParamRegImpl
28  */
29 
30 gx_engine::ParamMap *ParamRegImpl::pmap = 0;
31 
33  pmap = pm;
34  plugin = 0;
35  registerVar = registerVar_;
36  registerBoolVar = registerBoolVar_;
37  registerNonMidiVar = registerNonMidiVar_;
38  registerNonMidiFloatVar = registerNonMidiFloatVar_;
39  registerEnumVar = registerEnumVar_;
40  registerSharedEnumVar = registerSharedEnumVar_;
41  registerIEnumVar = registerIEnumVar_;
42 }
43 
44 float *ParamRegImpl::registerVar_(const char* id, const char* name, const char* tp,
45  const char* tooltip, float* var, float val,
46  float low, float up, float step) {
47  assert(step > 0);
48  assert(up > low);
49  if (!name[0]) {
50  assert(strrchr(id, '.'));
51  name = strrchr(id, '.')+1;
52  }
53  int n = strlen(tp);
54  if (n && tp[n-1] == 'A') {
55  if (pmap->hasId(id)) {
56  gx_engine::Parameter& p = (*pmap)[id];
57 #ifndef NDEBUG
59  id, name, (tp[0] == 'B' ? Parameter::Switch : gx_engine::Parameter::Continuous),
60  true, p.getFloat().value, val, low, up, step, true, false);
61  p2.set_desc(tooltip);
62  gx_engine::compare_parameter("Alias Parameter", &p, &p2);
63 #endif
64  return p.getFloat().value;
65  }
66  }
67  gx_engine::Parameter *p = 0;
68  int i = 0;
69  if (tp[0] == 'S') {
70  i = 1;
71  p = pmap->reg_par(id, name, var, val, low, up, step);
72  if (tp[1] == 'L') {
73  assert(step > 1);
74  p->set_log_display();
75  i = 2;
76  }
77  } else if (tp[0] == 'B') {
78  i = 1;
79  p = pmap->reg_par(id, name, var, val);
80  } else {
81  assert(false);
82  }
83  if (tp[i] == 'O') {
84  p->setSavable(false);
85  }
86  if (tooltip && tooltip[0]) {
87  p->set_desc(tooltip);
88  }
89  return var;
90 }
91 
92 void ParamRegImpl::registerBoolVar_(const char* id, const char* name, const char* tp,
93  const char* tooltip, bool* var, bool val) {
94  gx_engine::Parameter *p = pmap->reg_par(id, name, var, val);
95  if (tooltip && tooltip[0]) {
96  p->set_desc(tooltip);
97  }
98 }
99 
100 void ParamRegImpl::registerEnumVar_(const char *id, const char* name, const char* tp,
101  const char* tooltip, const value_pair* values, float *var,
102  float val, float low, float up, float step) {
103  if (!name[0]) {
104  assert(strrchr(id, '.'));
105  name = strrchr(id, '.')+1;
106  }
107  assert(step == 1.0);
108  gx_engine::Parameter *p = pmap->reg_enum_par(id, name, values, var, val, low);
109  if (tooltip && tooltip[0]) {
110  p->set_desc(tooltip);
111  }
112 }
113 
114 float *ParamRegImpl::registerSharedEnumVar_(const char *id, const char* name, const char* tp,
115  const char* tooltip, const value_pair* values, float *var,
116  float val, float low, float up, float step) {
117  if (!name[0]) {
118  assert(strrchr(id, '.'));
119  name = strrchr(id, '.')+1;
120  }
121  assert(step == 1.0);
122  int n = strlen(tp);
123  if (n && tp[n-1] == 'A') {
124  if (pmap->hasId(id)) {
125  gx_engine::Parameter& p = (*pmap)[id];
126 #ifndef NDEBUG
128  id, name, gx_engine::Parameter::Enum,
129  true, p.getFloat().value, val, low, up, step, true, false);
130  p2.set_desc(tooltip);
131  gx_engine::compare_parameter("Alias Parameter", &p, &p2);
132 #endif
133  return p.getFloat().value;
134  }
135  }
136  gx_engine::Parameter *p = pmap->reg_enum_par(id, name, values, var, val, low);
137  if (tooltip && tooltip[0]) {
138  p->set_desc(tooltip);
139  }
140  return var;
141 }
142 
143 void ParamRegImpl::registerIEnumVar_(const char *id, const char* name, const char* tp,
144  const char* tooltip, const value_pair* values,
145  int *var, int val) {
146  if (!name[0]) {
147  assert(strrchr(id, '.'));
148  name = strrchr(id, '.')+1;
149  }
150  gx_engine::Parameter *p = pmap->reg_enum_par(id, name, values, var, val);
151  if (tooltip && tooltip[0]) {
152  p->set_desc(tooltip);
153  }
154 }
155 
156 void ParamRegImpl::registerNonMidiVar_(const char * id, bool*var, bool preset, bool nosave) {
157  BoolParameter *p = pmap->reg_non_midi_par(id, var, preset);
158  if (nosave) {
159  p->setSavable(false);
160  }
161 }
162 
163 void ParamRegImpl::registerNonMidiFloatVar_(const char * id, float *var, bool preset, bool nosave,
164  float val, float low, float up, float step) {
165  FloatParameter *p = pmap->reg_non_midi_par(id, var, preset, val, low, up, step);
166  if (nosave) {
167  p->setSavable(false);
168  }
169 }
170 
171 
172 /****************************************************************
173  ** class Plugin
174  */
175 
177  : pdef(0),
178  p_box_visible(0),
179  p_plug_visible(0),
180  p_on_off(0),
181  p_position(0),
182  p_effect_post_pre(0) {
183  set_pdef(pl);
184 }
185 
186 static void delete_plugindef_instance(PluginDef *p) {
187  free((void*)(p->id));
188  free((void*)(p->name));
189  free((void*)(p->description));
190  free((void*)(p->category));
191  free((void*)(p->shortname));
192  if (p->groups) {
193  for (const char **q = p->groups; *q; q++) {
194  free((void*)(*q));
195  }
196  delete[] p->groups;
197  }
198  delete p;
199 }
200 
202  : pdef(0),
203  p_box_visible(0),
204  p_plug_visible(0),
205  p_on_off(0),
206  p_position(0),
207  p_effect_post_pre(0) {
208  PluginDef *p = new PluginDef();
209  p->delete_instance = delete_plugindef_instance;
211  while (jp.peek() != gx_system::JsonParser::end_object) {
213  if (jp.read_kv("version", p->version) ||
214  jp.read_kv("flags", p->flags)) {
215  } else if (jp.current_value() == "id") {
217  p->id = strdup(jp.current_value().c_str());
218  } else if (jp.current_value() == "name") {
220  p->name = strdup(jp.current_value().c_str());
221  } else if (jp.current_value() == "groups") {
223  std::vector<std::string> v;
224  while (jp.peek() != gx_system::JsonParser::end_array) {
226  v.push_back(jp.current_value());
227  }
229  const char **pg = new const char*[v.size()+1];
230  p->groups = pg;
231  for (std::vector<std::string>::iterator i = v.begin(); i != v.end(); ++i) {
232  *pg++ = strdup(i->c_str());
233  }
234  *pg++ = 0;
235  } else if (jp.current_value() == "description") {
237  p->description = strdup(jp.current_value().c_str());
238  } else if (jp.current_value() == "category") {
240  p->category = strdup(jp.current_value().c_str());
241  } else if (jp.current_value() == "shortname") {
243  p->shortname = strdup(jp.current_value().c_str());
244  }
245  }
247  p->flags &= ~PGNI_UI_REG;
248  std::string s = p->id;
249  std::string id = "ui."+s;
250  if (pmap.hasId(id)) {
251  p_box_visible = &pmap[id].getBool();
252  }
253  id = s+".s_h";
254  if (pmap.hasId(id)) {
255  p_plug_visible = &pmap[id].getBool();
256  }
257  p_on_off = &pmap[s+".on_off"].getBool();
258  p_position = &pmap[s+".position"].getInt();
259  p_effect_post_pre = &pmap[s+".pp"].getInt();
260  set_pdef(p);
261 }
262 
264  jw.begin_object();
265  jw.write_kv("version", pdef->version);
266  jw.write_kv("flags", pdef->flags); //FIXME
267  jw.write_kv("id", pdef->id);
268  if (pdef->name) {
269  jw.write_kv("name", pdef->name);
270  }
271  if (pdef->groups) {
272  jw.write_key("groups");
273  jw.begin_array();
274  for (const char **p = pdef->groups; *p; p++) {
275  jw.write(*p);
276  }
277  jw.end_array();
278  }
279  if (pdef->description) {
280  jw.write_kv("description", pdef->description);
281  }
282  if (pdef->category) {
283  jw.write_kv("category", pdef->category);
284  }
285  if (pdef->shortname) {
286  jw.write_kv("shortname", pdef->shortname);
287  }
288  jw.end_object();
289 }
290 
292  string s = pdef->id;
293  p_on_off = param.reg_par(s+".on_off",N_("on/off"), (bool*)0, !(pdef->flags & (PGN_GUI|PGN_ALTERNATIVE)));
294  if (!(pdef->load_ui || (pdef->flags & PGN_GUI))) {
295  p_on_off->setSavable(false);
296  }
297  p_on_off->set_midi_blocked(true);
298  p_on_off->signal_changed_bool().connect(
299  sigc::hide(sigc::mem_fun(seq, &EngineControl::set_rack_changed)));
300  if ((pdef->load_ui || pdef->flags & PGN_GUI) &&
301  (pdef->flags & PGNI_DYN_POSITION || !(pdef->flags & PGN_FIXED_GUI))) {
302  p_box_visible = param.reg_non_midi_par("ui." + s, (bool*)0, true);
303  p_plug_visible = param.reg_non_midi_par(s + ".s_h", (bool*)0, false);
304  }
305  p_position = param.reg_non_midi_par(s + ".position", (int*)0, true, pos_tmp, -9999, 9999);
306  int pp = (pdef->flags & PGN_POST ? 0 : 1);
307  bool savable = false;
308  if (pdef->flags & PGNI_DYN_POSITION) {
309  // PLUGIN_POS_RACK .. PLUGIN_POS_POST_START-1
310  p_position->signal_changed_int().connect(
311  sigc::hide(sigc::mem_fun(seq, &EngineControl::set_rack_changed)));
312  if (pdef->mono_audio || (pdef->flags & PGN_POST_PRE)) {
313  if (pdef->flags & PGN_PRE) {
314  pp = 1;
315  } else if (pdef->flags & PGN_POST) {
316  pp = 0;
317  } else {
318  savable = true;
319  }
320  }
321  } else {
322  p_position->setSavable(false);
323  }
324  static const value_pair post_pre[] = {{N_("post")}, {N_("pre")}, {0}};
325  p_effect_post_pre = param.reg_enum_par(s + ".pp", "select", post_pre, (int*)0, pp);
326  p_effect_post_pre->setSavable(savable);
327  if (savable) {
328  p_effect_post_pre->signal_changed_int().connect(
329  sigc::hide(sigc::mem_fun(seq, &EngineControl::set_rack_changed)));
330  }
331 }
332 
333 void Plugin::copy_position(const Plugin& plugin) {
334  set_position(plugin.get_position());
336 }
337 
338 
339 /****************************************************************
340  ** class PluginList
341  */
342 
344 
346  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); ++p) {
347  PluginDef *pdef = p->second->get_pdef();
348  if (!(pdef->flags & PGNI_NOT_OWN)) {
349  if (pdef->delete_instance) {
350  pdef->delete_instance(pdef);
351  }
352  delete p->second;
353  }
354  }
355  pmap.clear();
356 }
357 
359  cleanup();
360 }
361 
363  : PluginListBase(), seq(seq_) {
364  plugin_pos[PLUGIN_POS_START] = -1000;
365  plugin_pos[PLUGIN_POS_RACK] = 1;
366  plugin_pos[PLUGIN_POS_END] = 1000;
367  plugin_pos[PLUGIN_POS_RACK_STEREO] = 1;
368 };
369 
371 }
372 
373 Plugin *PluginListBase::find_plugin(const std::string& id) const {
374  pluginmap::const_iterator p = pmap.find(id);
375  if (p == pmap.end()) {
376  return 0;
377  }
378  return p->second;
379 }
380 
381 Plugin *PluginListBase::lookup_plugin(const std::string& id) const {
382  Plugin *p = find_plugin(id);
383  if (!p) {
385  _("lookup plugin"),
386  boost::format("id not found: %1%") % id);
387  }
388  return p;
389 }
390 
391 int PluginList::load_library(const string& path, PluginPos pos) {
392  void* handle = dlopen(path.c_str(), RTLD_LOCAL|RTLD_NOW);
393  if (!handle) {
395  _("Plugin Loader"),
396  boost::format(_("Cannot open library: %1%")) % dlerror());
397  return -1;
398  }
399  dlerror(); // reset errors
400  plugin_inifunc get_gx_plugin = (plugin_inifunc) dlsym(handle, "get_gx_plugin");
401  const char *dlsym_error = dlerror();
402  if (dlsym_error) {
404  _("Plugin Loader"),
405  boost::format(_("Cannot load symbol 'get_gx_plugin': %1%")) % dlsym_error);
406  dlclose(handle);
407  return -1;
408  }
409  int n = get_gx_plugin(0, 0);
410  if (n <= 0) {
411  return -1;
412  }
413  int cnt = 0;
414  for (int i = 0; i < n; i++) {
415  PluginDef *p;
416  if (get_gx_plugin(i, &p) < 0) {
417  continue;
418  }
419  if (!add(p, pos)) {
420  cnt++;
421  gx_print_info(_("Plugin Loader"), Glib::ustring::compose("loaded[%1]: %2", path, p->id));
422  }
423  }
424  return cnt;
425 }
426 
427 int PluginList::load_from_path(const string& path, PluginPos pos) {
428  DIR *dp;
429  struct dirent *dirp;
430  if((dp = opendir(path.c_str())) == NULL) {
432  _("Plugin Loader"),
433  boost::format(_("Error opening '%1%'")) % path);
434  return -1;
435  }
436  int cnt = 0;
437  while ((dirp = readdir(dp)) != NULL) {
438  string n = dirp->d_name;
439  if (n.size() > 3 && n.compare(n.size()-3,3,".so") == 0) {
440  int res = load_library(path+n, pos);
441  if (res > 0) {
442  cnt += res;
443  }
444  }
445  }
446  closedir(dp);
447  return cnt;
448 }
449 
453  return 0;
454  }
456  _("Plugin Loader"),
457  boost::format(_("Plugin '%1%' has wrong version %2$#4x (current version: %3$#4x)"))
458  % p->id % p->version % PLUGINDEF_VERSION);
459  return -1;
460 }
461 
463  PluginDef *p = pl->get_pdef();
464  insert_remove(p->id, false);
465 #ifndef NDEBUG // avoid unused variable compiler warning
466  size_t n = pmap.erase(p->id);
467  assert(n == 1);
468 #else
469  pmap.erase(p->id);
470 #endif
471  if (!(p->flags & PGNI_NOT_OWN)) {
472  if (p->delete_instance) {
473  p->delete_instance(p);
474  }
475  delete pl;
476  }
477 }
478 
480  const char *id = pvars->get_pdef()->id;
481  pair<pluginmap::iterator,bool> ret = pmap.insert(map_pair(id, pvars));
482  if (!ret.second) {
484  _("Plugin Loader"),
485  boost::format(_("Plugin '%1%' already exists: skipped")) % id);
486  return -1;
487  }
488  insert_remove(id, true);
489  return 0;
490 }
491 
493  pmap[pvars->get_pdef()->id]->set_pdef(pvars->get_pdef());
494 }
495 
496 int PluginList::add_module(Plugin *pvars, PluginPos pos, int flags) {
497  const int mode_mask = (PGN_MODE_NORMAL|PGN_MODE_BYPASS|PGN_MODE_MUTE); // all mode bits
498  PluginDef *p = pvars->get_pdef();
499  p->flags |= flags;
500  if (!(p->flags & mode_mask)) {
501  p->flags |= PGN_MODE_NORMAL;
502  }
503  if (p->stereo_audio) {
504  p->flags |= PGN_STEREO;
505  }
506  if (p->load_ui) {
507  p->flags |= PGN_GUI;
508  }
509  int ipos = pos;
510  if (ipos == PLUGIN_POS_RACK) {
511  p->flags |= PGNI_DYN_POSITION;
512  if (p->flags & PGN_STEREO) {
513  ipos = PLUGIN_POS_RACK_STEREO;
514  }
515  }
516  if (pvars->p_position) {
517  pvars->set_position(plugin_pos[ipos]);
518  } else {
519  pvars->pos_tmp = plugin_pos[ipos];
520  }
521  int ret = insert_plugin(pvars);
522  if (ret != 0) {
523  return ret;
524  }
525  if (!(p->flags & PGN_ALTERNATIVE)) {
526  // normal case: position will not be set by ModuleSelector
527  plugin_pos[ipos]++;
528  }
529  return 0;
530 }
531 
532 int PluginList::add(Plugin *pvars, PluginPos pos, int flags) {
533  if (check_version(pvars->get_pdef()) != 0) {
534  return -1;
535  }
536  return add_module(pvars, pos, flags|PGNI_NOT_OWN);
537 }
538 
540  if (check_version(p) != 0) {
541  return 0;
542  }
543  Plugin *pl = new Plugin(p);
544  int ret = add_module(pl, pos, flags);
545  if (ret != 0) {
546  delete pl;
547  return 0;
548  }
549  return pl;
550 }
551 
552 int PluginList::add(PluginDef **p, PluginPos pos, int flags) {
553  int count = 0;
554  while (*p) {
555  if (add(*p++, pos, flags) == 0) {
556  count++;
557  }
558  }
559  return count;
560 }
561 
562 int PluginList::add(plugindef_creator *p, PluginPos pos, int flags) {
563  int count = 0;
564  while (*p) {
565  if (add((*p++)(), pos, flags) == 0) {
566  count++;
567  }
568  }
569  return count;
570 }
571 
572 static const char* tr_name(const char *name) {
573  if (name && name[0]) {
574  return gettext(name);
575  }
576  return "";
577 }
578 
580  groups.insert(pd->id, tr_name(pd->name));
581  const char **gp = pd->groups;
582  if (gp) {
583  while (*gp) {
584  string id = *gp++;
585  const char *name = *gp++;
586  if (!name) {
587  break;
588  }
589  if (id[0] == '.') {
590  id = id.substr(1);
591  } else {
592  id = string(pd->id) + "." + id;
593  }
594  groups.insert(id, tr_name(name));
595  }
596  }
597 }
598 
600  groups.erase(pd->id);
601  const char **gp = pd->groups;
602  if (gp) {
603  while (*gp) {
604  string id = *gp++;
605  const char *name = *gp++;
606  if (!name) {
607  break;
608  }
609  if (id[0] == '.') {
610  id = id.substr(1);
611  } else {
612  id = string(pd->id) + "." + id;
613  }
614  groups.erase(id);
615  }
616  }
617 }
618 
620  PluginDef *pdef = pl->get_pdef();
621  string s = pdef->id;
622  param.unregister(pl->p_on_off);
623  pl->p_on_off = param.reg_par(s+".on_off",N_("on/off"), (bool*)0, !(pdef->flags & (PGN_GUI|PGN_ALTERNATIVE)));
624  if (!(pdef->load_ui || (pdef->flags & PGN_GUI))) {
625  pl->p_on_off->setSavable(false);
626  }
627  pl->p_on_off->signal_changed_bool().connect(
628  sigc::hide(sigc::mem_fun(seq, &EngineControl::set_rack_changed)));
629 }
630 
632  pl->register_vars(param, seq);
633  PluginDef *pd = pl->get_pdef();
634  if (pd->register_params) {
635  preg.plugin = pd;
636  pd->register_params(preg);
637  }
638 }
639 
641  PluginDef *pd = pl->get_pdef();
642  param.unregister(pl->p_on_off);
643  param.unregister(pl->p_position);
644  param.unregister(pl->p_box_visible);
645  param.unregister(pl->p_plug_visible);
646  param.unregister(pl->p_effect_post_pre);
647  std::vector<const std::string*> l;
648  if (pd->register_params) {
649  string s = pd->id;
650  s += ".";
651  for (ParamMap::iterator i = param.begin(); i != param.end(); ++i) {
652  if (i->first.compare(0, s.size(), s) == 0) {
653  assert(i->second->isInPreset());
654  l.push_back(&i->first);
655  }
656  }
657  }
658  for (std::vector<const std::string*>::iterator i = l.begin(); i != l.end(); ++i) {
659  param.unregister(**i);
660  }
661 }
662 
664  registerGroup(pl->get_pdef(), groups);
665  ParamRegImpl preg(&param);
666  registerParameter(pl, param, preg);
667 }
668 
670  ParamRegImpl preg(&param);
671  unregisterParameter(pl, param);
672  unregisterGroup(pl->get_pdef(), groups);
673 }
674 
676  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
677  registerGroup(p->second->get_pdef(), groups);
678  }
679  ParamRegImpl preg(&param);
680  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
681  registerParameter(p->second, param, preg);
682  }
683 }
684 
686  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
687  ui.load(p->second);
688  }
689 }
690 
691 static bool plugin_order(Plugin* p1, Plugin* p2) {
692  return p1->position_weight() < p2->position_weight();
693 }
694 
695 void PluginList::ordered_mono_list(list<Plugin*>& mono, int mode) {
696  mono.clear();
697  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
698  Plugin *pl = p->second;
699  if (pl->get_on_off() && pl->get_pdef()->mono_audio && (pl->get_pdef()->flags & mode)) {
700  mono.push_back(pl);
701  }
702  pl->p_on_off->set_midi_blocked(!(pl->get_box_visible()));
703  }
704  mono.sort(plugin_order);
705 
706  // print active plugins
707  // for (list<Plugin*>::const_iterator i = mono.begin(); i != mono.end(); ++i) {
708  // printf("mono_list %s\n", (*i)->get_pdef()->id);
709  // }
710  // printf("\n");
711 }
712 
713 void PluginList::ordered_stereo_list(list<Plugin*>& stereo, int mode) {
714  stereo.clear();
715  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
716  Plugin *pl = p->second;
717  if (pl->get_on_off() && pl->get_pdef()->stereo_audio && (pl->get_pdef()->flags & mode)) {
718  stereo.push_back(pl);
719  }
720  pl->p_on_off->set_midi_blocked(!(pl->get_box_visible()));
721  }
722  stereo.sort(plugin_order);
723 }
724 
725 void PluginList::ordered_list(list<Plugin*>& l, bool stereo, int flagmask, int flagvalue) {
726  flagmask |= (PGN_STEREO | PGN_MODE_NORMAL);
727  if (stereo) {
728  flagvalue |= PGN_STEREO;
729  }
730  flagvalue |= PGN_MODE_NORMAL;
731  l.clear();
732  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
733  PluginDef *pd = p->second->get_pdef();
734  if (((pd->flags & flagmask) == flagvalue) || (!stereo && strcmp(pd->id, "ampstack") == 0)) {
735  l.push_back(p->second);
736  }
737  }
738  l.sort(plugin_order);
739 }
740 
742  jw.begin_array();
743  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
744  p->second->writeJSON(jw);
745  }
746  jw.end_array();
747 }
748 
751  while (jp.peek() != gx_system::JsonParser::end_array) {
752  Plugin *p = new Plugin(jp, param);
753  pmap.insert(map_pair(p->get_pdef()->id, p));
754  insert_remove(p->get_pdef()->id, true);
755  }
757 }
758 
759 void PluginList::set_samplerate(int samplerate) {
760  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
761  inifunc f = p->second->get_pdef()->set_samplerate;
762  if (f) {
763  f(samplerate, p->second->get_pdef());
764  }
765  }
766 }
767 
768 #ifndef NDEBUG
769 void PluginList::printlist(bool order) {
770  list<Plugin*> pl_mono, pl_stereo;
771  for (pluginmap::iterator p = pmap.begin(); p != pmap.end(); p++) {
772  if (p->second->get_pdef()->flags & PGN_STEREO) {
773  pl_stereo.push_back(p->second);
774  } else {
775  pl_mono.push_back(p->second);
776  }
777  }
778  if (order) {
779  pl_mono.sort(plugin_order);
780  pl_stereo.sort(plugin_order);
781  }
782  gx_engine::printlist("Plugin Map", pl_mono);
783  gx_engine::printlist(0, pl_stereo, false);
784 }
785 
786 void printlist(const char *title, const list<Plugin*>& modules, bool header) {
787  if (!getenv("GUITARIX_MODULE_DEBUG")) {
788  return;
789  }
790  const char *fmth = "%1s %-25s %5s %5s %3s %2s %3s %8s\n";
791  const char *fmtl = "%1s %-25s %5d %5d %3d %2d %3d %8s\n";
792  static int cnt = 0;
793  if (header) {
794  printf("%d %s:\n", ++cnt, title);
795  printf(fmth, "F", "id","wght","pos","pre","on","vis","channels");
796  } else {
797  printf("\n");
798  }
799  for (list<Plugin*>::const_iterator i = modules.begin(); i != modules.end(); ++i) {
800  Plugin *p = *i;
801  PluginDef *pd = p->get_pdef();
802  const char *c = "-";
803  if (pd->mono_audio) {
804  c = "mono";
805  } else if (pd->stereo_audio) {
806  c = "stereo";
807  }
808  const char *f;
809  if (pd->flags & PGN_GUI) {
810  f = "";
811  } else if (pd->flags & PGN_ALTERNATIVE) {
812  f = "A";
813  } else {
814  f = "-";
815  }
816  printf(fmtl, f, pd->id, p->position_weight(), p->get_position(),
817  p->get_effect_post_pre(), p->get_on_off(),
818  (p->p_box_visible ? p->get_box_visible() : false), c);
819  }
820 }
821 #endif
822 
823 } // !namespace gx_engine
#define PLUGINDEF_VERMINOR_MASK
Definition: gx_plugin.h:178
void write_kv(const char *key, float v)
Definition: gx_json.h:81
void registerGroup(PluginDef *pd, ParameterGroups &groups)
void gx_print_info(const char *, const std::string &)
Definition: gx_logging.cpp:183
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
sigc::signal< void, int > & signal_changed_int()
Definition: gx_parameter.h:488
PluginDef * get_pdef()
BoolParameter * reg_non_midi_par(const string &id, bool *var, bool preset, bool std=false)
Definition: gx_parameter.h:593
void unregisterPlugin(Plugin *pl, ParamMap &param, ParameterGroups &groups)
map< string, Parameter * >::const_iterator iterator
Definition: gx_parameter.h:531
void setSavable(bool v)
Definition: gx_parameter.h:170
void unregister(Parameter *p)
int load_from_path(const string &path, PluginPos pos=PLUGIN_POS_RACK)
sigc::signal< void, const char *, bool > insert_remove
float *(* registerSharedEnumVar)(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:135
void end_array(bool nl=false)
Definition: gx_json.cpp:192
void printlist(const char *title, const list< Plugin * > &modules, bool header=true)
PluginDef * plugin
Definition: gx_plugin.h:123
void set_pdef(PluginDef *p)
#define N_(String)
const char * name
Definition: gx_plugin.h:186
void(* inifunc)(unsigned int samplingFreq, PluginDef *plugin)
Definition: gx_plugin.h:146
sigc::signal< void, bool > & signal_changed_bool()
Definition: gx_parameter.h:494
void register_vars(ParamMap &param, EngineControl &seq)
void writeJSON(gx_system::JsonWriter &jw)
void set_effect_post_pre(int v) const
Plugin * lookup_plugin(const std::string &id) const
PluginList(EngineControl &seq)
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
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
bool hasId(const string &id) const
Definition: gx_parameter.h:534
const char * description
Definition: gx_plugin.h:189
void ordered_list(list< Plugin * > &l, bool stereo, int flagmask, int flagvalue)
void set_position(int v) const
void compare_parameter(const char *title, Parameter *p1, Parameter *p2, bool all=false)
void registerParameter(Plugin *pl, ParamMap &param, ParamRegImpl &preg)
void write_key(const char *p, bool nl=false)
Definition: gx_json.cpp:200
const char ** groups
Definition: gx_plugin.h:187
iterator begin() const
Definition: gx_parameter.h:532
void gx_print_fatal(const char *, const std::string &)
Definition: gx_logging.cpp:177
int load_library(const string &path, PluginPos pos=PLUGIN_POS_RACK)
const char * shortname
Definition: gx_plugin.h:191
int insert_plugin(Plugin *pvars)
#define PLUGINDEF_VERMAJOR_MASK
Definition: gx_plugin.h:177
Plugin(PluginDef *pl=0)
const char * category
Definition: gx_plugin.h:190
void unregisterParameter(Plugin *pl, ParamMap &param)
void(* registerIEnumVar)(const char *id, const char *name, const char *tp, const char *tooltip, const value_pair *values, int *var, int val)
Definition: gx_plugin.h:138
deletefunc delete_instance
Definition: gx_plugin.h:204
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
bool read_kv(const char *key, float &v)
Definition: gx_json.cpp:511
void insert(const string &id, const string &group)
Definition: gx_parameter.h:67
void copy_position(const Plugin &plugin)
#define PLUGINDEF_VERSION
Definition: gx_plugin.h:179
registerfunc register_params
Definition: gx_plugin.h:200
void set_midi_blocked(bool v)
Definition: gx_parameter.h:183
void registerPlugin(Plugin *pl, ParamMap &param, ParameterGroups &groups)
void unregisterGroup(PluginDef *pd, ParameterGroups &groups)
const char * id
Definition: gx_plugin.h:185
int get_position() const
void delete_module(Plugin *pl)
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
void readJSON(gx_system::JsonParser &jp, ParamMap &pmap)
void erase(const string &id)
Definition: gx_parameter.h:71
virtual bool load(Plugin *p)=0
int flags
Definition: gx_plugin.h:183
int get_effect_post_pre() const
void(* registerNonMidiVar)(const char *id, bool *var, bool preset, bool nosave)
Definition: gx_plugin.h:129
PluginDef *(* plugindef_creator)()
Plugin * find_plugin(const std::string &id) const
FloatParameter * reg_par(const string &id, const string &name, float *var, float std, float lower, float upper, float step)
Definition: gx_parameter.h:551
void update_plugin(Plugin *pvars)
void set_samplerate(int samplerate)
FloatParameter & getFloat()
Definition: gx_parameter.h:451
void gx_print_warning(const char *, const std::string &)
Definition: gx_logging.cpp:161
void ordered_mono_list(list< Plugin * > &mono, int mode)
process_stereo_audio stereo_audio
Definition: gx_plugin.h:196
void printlist(bool ordered=true)
void(* registerNonMidiFloatVar)(const char *id, float *var, bool preset, bool nosave, float val, float low, float up, float step)
Definition: gx_plugin.h:130
inifunc set_samplerate
Definition: gx_plugin.h:198
virtual void set_rack_changed()=0
process_mono_audio mono_audio
Definition: gx_plugin.h:195
void set_desc(const string &desc)
Definition: gx_parameter.h:177
EnumParameter * reg_enum_par(const string &id, const string &name, const value_pair *vl, int *var, int std=0)
Definition: gx_parameter.h:573
void rescueParameter(Plugin *pl, ParamMap &param)
string current_value() const
Definition: gx_json.h:143
int add(Plugin *pl, PluginPos pos, int flags)
token next(token expect=no_token)
Definition: gx_json.cpp:496
void registerAllPlugins(ParamMap &param, ParameterGroups &groups)
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
bool get_on_off() const
int version
Definition: gx_plugin.h:182
pair< const std::string, Plugin * > map_pair
bool get_box_visible() const
uiloader load_ui
Definition: gx_plugin.h:201
int check_version(PluginDef *p)
void(* registerBoolVar)(const char *id, const char *name, const char *tp, const char *tooltip, bool *var, bool val)
Definition: gx_plugin.h:127
void ordered_stereo_list(list< Plugin * > &stereo, int mode)
void append_rack(UiBuilderBase &ui)
iterator end() const
Definition: gx_parameter.h:533
void end_object(bool nl=false)
Definition: gx_json.cpp:176
void writeJSON(gx_system::JsonWriter &jw)
int(* plugin_inifunc)(unsigned int idx, PluginDef **p)
Definition: gx_plugin.h:210