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