Guitarix
gx_preset.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * --------------------------------------------------------------------------
19  */
20 
21 /* --------------------------------------------------------------------------
22 
23  This is the gx_head preset handling functions
24 
25  ---------------------------------------------------------------------------*/
26 
27 #include <sys/stat.h>
28 
29 #include "engine.h" // NOLINT
30 
31 namespace gx_preset {
32 
33 /****************************************************************
34  ** class PresetIO
35  */
36 
39  gx_engine::ParamMap& param_,
41  UnitRacks& rack_units_)
42  : gx_system::AbstractPresetIO(),
43  mctrl(mctrl_),
44  convolver(cvr_),
45  param(param_),
46  opt(opt_),
47  plist(),
48  m(0),
49  rack_units(rack_units_) {
50 }
51 
53  clear();
54 }
55 
56 void PresetIO::clear() {
57  plist.clear();
58  delete m;
59  m = 0;
60 }
61 
62 bool PresetIO::midi_in_preset() {
63  const char *i = "system.midi_in_preset";
64  if (param.hasId(i)) {
65  return param[i].getBool().get_value();
66  } else {
67  return false;
68  }
69 }
70 
72  clear();
73  for (gx_engine::ParamMap::iterator i = param.begin(); i != param.end(); ++i) {
74  if (i->second->isInPreset() && i->second->isSavable()) {
75  i->second->stdJSON_value();
76  plist.push_back(i->second);
77  }
78  }
79  read_intern(jp, 0, head);
80 }
81 
82 void PresetIO::fixup_parameters(const gx_system::SettingsFileHeader& head) {
83  assert(param.hasId("jconv.wet_dry"));
84  if (head.is_current()) {
85  return;
86  }
87  if (head.get_major() == 1 && head.get_minor() < 2) {
88  if (param.hasId("jconv.wet_dry")) {
89  gx_engine::Parameter& p = param["jconv.wet_dry"];
90  if (p.isFloat()) {
91  p.getFloat().convert_from_range(-1, 1);
92  }
93  }
94  }
95 }
96 
97 static std::string replaced_id(const std::string& s) {
98  const char *old_new[][2] = {
99  { "beat_detector.stepper", "midi_out.beat_detector.stepper" },
100  { "beat_detector.note_off", "midi_out.beat_detector.note_off" },
101  { "beat_detector.atack_gain", "midi_out.beat_detector.atack_gain" },
102  { "beat_detector.beat_gain", "midi_out.beat_detector.beat_gain" },
103  { "beat_detector.midi_gain", "midi_out.beat_detector.midi_gain" },
104  // begin ui.*
105  // ui.<name> -> ui.<id> (rack unit visible)
106  { "ui.3 Band EQ", "ui.tonemodul" },
107  { "ui.BiQuad Filter", "ui.biquad" },
108  { "ui.Cabinet", "ui.cab" },
109  { "ui.Preamp", "ui.pre" },
110  { "ui.Chorus", "ui.chorus" },
111  { "ui.Chorus Mono", "ui.chorus_mono" },
112  { "ui.Compressor", "ui.compressor" },
113  { "ui.Convolver", "ui.jconv" },
114  { "ui.Crybaby", "ui.crybaby" },
115  { "ui.Delay", "ui.delay" },
116  { "ui.Echo", "ui.echo" },
117  { "ui.Feedback", "ui.feedback" },
118  { "ui.Flanger", "ui.flanger" },
119  { "ui.Flanger Mono", "ui.flanger_mono" },
120  { "ui.Freeverb", "ui.freeverb" },
121  { "ui.ImpulseResponse", "ui.IR" },
122  { "ui.Midi Out", "ui.midi_out" },
123  { "ui.Moog Filter", "ui.moog" },
124  { "ui.Multi Band Distortion", "ui.gx_distortion" },
125  { "ui.Oscilloscope", "ui.oscilloscope" },
126  { "ui.Overdrive", "ui.overdrive" },
127  { "ui.Phaser", "ui.phaser" },
128  { "ui.Phaser Mono", "ui.phaser_mono" },
129  { "ui.Postamp", "ui.ampmodul" },
130  { "ui.Scaleable EQ", "ui.eqs" },
131  { "ui.Stereo Delay", "ui.stereodelay" },
132  { "ui.Stereo Echo", "ui.stereoecho" },
133  { "ui.Stereo Verb", "ui.stereoverb" },
134  { "ui.Tonestack", "ui.amp.tonestack" },
135  { "ui.Tremolo", "ui.tremolo" },
136  { "ui.Vibe", "ui.univibe" },
137  { "ui.Vibe Mono", "ui.univibe_mono" },
138  { "ui.Zita Rev1", "ui.zita_rev1" },
139  { "ui.abGate", "ui.abgate" },
140  { "ui.low high pass", "ui.low_highpass" },
141  { "Rev.Rocket.s_h", "rev_rocket.s_h"},
142  { "Rev.Rocket.position", "rev_rocket.position"},
143  { "Rev.Rocket.pp", "rev_rocket.pp"},
144  { "ui.Rev.Rocket", "ui.rev_rocket"},
145  {0}
146  };
147  for (const char *(*p)[2] = old_new; (*p)[0]; ++p) {
148  if (s == (*p)[0]) {
149  return (*p)[1];
150  }
151  }
152  return "";
153 }
154 
156 public:
157  std::string id;
158  int weight;
159  UnitPositionID(const string& id_, const UnitPosition& u);
160  bool operator<(const UnitPositionID& v) const { return weight < v.weight; }
161 };
162 
163 UnitPositionID::UnitPositionID(const string& id_, const UnitPosition& u)
164  : UnitPosition(u),
165  id(id_),
166  weight(position - 1000 * pp) {
167 }
168 
169 void UnitsCollector::get_list(std::vector<std::string>& l, bool stereo, gx_engine::ParamMap& param) {
170  std::vector<UnitPositionID> v;
171  for (std::map<std::string,UnitPosition>::iterator i = m.begin(); i != m.end(); ++i) {
172  if (i->first == "jconv" && i->second.position < 0) {
173  i->second.position = 99; // very old presets
175  jp.get_ostream() << i->second.position;
176  jp.start_parser();
177  param[i->first+".position"].readJSON_value(jp);
178  }
179  if (i->first == "cab") {
180  if (i->second.position < 0) {
181  i->second.position = 98; // very old presets
183  jp.get_ostream() << i->second.position;
184  jp.start_parser();
185  param[i->first+".position"].readJSON_value(jp);
186  }
187  if (i->second.pp < 0) {
188  i->second.pp = 0;
190  jp.get_ostream() << i->second.pp;
191  jp.start_parser();
192  param[i->first+".pp"].readJSON_value(jp);
193  }
194  }
195  if (i->second.position >= 0 && i->second.show) {
196  if ((stereo && i->second.pp < 0) || (!stereo && i->second.pp >= 0)) {
197  if (!i->second.visible) { // make sure ui.XX is set for old presets
198  i->second.visible = true;
200  jp.put('1');
201  jp.start_parser();
202  param["ui."+i->first].readJSON_value(jp);
203  }
204  v.push_back(UnitPositionID(i->first, i->second));
205  }
206  }
207  }
208  l.clear();
209  std::sort(v.begin(), v.end());
210  int pp = 1;
211  for (std::vector<UnitPositionID>::iterator j = v.begin(); j != v.end(); ++j) {
212  if (!stereo && j->pp != pp) {
213  pp = j->pp;
214  l.push_back("ampstack");
215  }
216  l.push_back(j->id);
217  }
218  if (!stereo && pp) {
219  l.push_back("ampstack");
220  }
221  /*
222  cerr << "SL";
223  for (std::vector<std::string>::iterator ii = l.begin(); ii != l.end(); ++ii) {
224  cerr << " '" << *ii << "'";
225  }
226  cerr << endl;
227  */
228 }
229 
230 bool PresetIO::convert_old(gx_system::JsonParser &jp) {
231  const std::string& s = jp.current_value();
232  if (s == "system.mainwin_x") {
234  opt.mainwin_x = jp.current_value_int();
235  return true;
236  }
237  if (s == "system.mainwin_y") {
239  opt.mainwin_y = jp.current_value_int();
240  return true;
241  }
242  if (s == "system.mainwin_height") {
244  opt.mainwin_height = jp.current_value_int();
245  return true;
246  }
247  if (s == "system.mainwin_rack_height") {
249  opt.window_height = jp.current_value_int();
250  return true;
251  }
252  if (s == "system.preset_window_height") {
254  opt.preset_window_height = jp.current_value_int();
255  return true;
256  }
257  if (s == "oscilloscope.bufferset") {
259  opt.mul_buffer = jp.current_value_int();
260  return true;
261  }
262  if (s == "ui.skin_name") {
264  opt.skin_name = jp.current_value();
265  return true;
266  }
267  if (s == "ui.latency_nowarn") {
269  opt.no_warn_latency = jp.current_value_int();
270  return true;
271  }
272  if (s == "system.order_rack_h") {
274  opt.system_order_rack_h = jp.current_value_int();
275  return true;
276  }
277  if (s == "system.show_value") {
279  opt.system_show_value = jp.current_value_int();
280  return true;
281  }
282  if (s == "system.show_tooltips") {
284  opt.system_show_tooltips = jp.current_value_int();
285  return true;
286  }
287  if (s == "system.animations") {
289  opt.system_animations = jp.current_value_int();
290  return true;
291  }
292  if (s == "system.show_presets") {
294  opt.system_show_presets = jp.current_value_int();
295  return true;
296  }
297  if (s == "system.show_toolbar") {
299  opt.system_show_toolbar = jp.current_value_int();
300  return true;
301  }
302  if (s == "system.show_rack") {
304  opt.system_show_rack = jp.current_value_int();
305  return true;
306  }
307 
308  return false;
309 }
310 
311 static inline bool endswith(const std::string& s, int n, const char *t) {
312  return s.compare(std::max<int>(0, s.size()-n), n, t) == 0;
313 }
314 
315 static inline bool startswith(const std::string& s, int n, const char *t) {
316  return s.compare(0, n, t) == 0;
317 }
318 
319 void PresetIO::collectRackOrder(gx_engine::Parameter *p, gx_system::JsonParser &jp, UnitsCollector& u) {
320  const std::string& s = p->id();
321  if (startswith(s, 3, "ui.")) {
322  if (jp.current_value_int()) {
323  std::string ss = s.substr(3);
324  u.set_visible(ss, true);
325  u.set_show(ss, true);
326  }
327  } else if (endswith(s, 7, ".on_off")) {
328  if (jp.current_value_int()) {
329  u.set_show(s.substr(0, s.size()-7), true);
330  }
331  } else if (endswith(s, 9, ".position")) {
332  u.set_position(s.substr(0, s.size()-9), jp.current_value_int());
333  } else if (endswith(s, 3, ".pp")) {
334  u.set_pp(s.substr(0, s.size()-3), (jp.current_value() == "pre" ? 1 : 0));
335  }
336 }
337 
338 void PresetIO::read_parameters(gx_system::JsonParser &jp, bool preset) {
339  UnitsCollector u;
341  do {
344  if (!param.hasId(jp.current_value())) {
345  if (convert_old(jp)) {
346  continue;
347  }
348  std::string s = replaced_id(jp.current_value());
349  if (s.empty()) {
351  _("recall settings"),
352  _("unknown parameter: ")+jp.current_value());
353  jp.skip_object();
354  continue;
355  }
356  p = &param[s];
357  } else {
358  p = &param[jp.current_value()];
359  }
360  if (!preset and p->isInPreset()) {
362  _("recall settings"),
363  _("preset-parameter ")+p->id()+_(" in settings"));
364  jp.skip_object();
365  continue;
366  } else if (preset and !p->isInPreset()) {
368  _("recall settings"),
369  _("non preset-parameter ")+p->id()+_(" in preset"));
370  jp.skip_object();
371  continue;
372  } else if (!p->isSavable()) {
374  _("recall settings"),
375  _("non saveable parameter ")+p->id()+_(" in settings"));
376  jp.skip_object();
377  continue;
378  }
379  p->readJSON_value(jp);
380  collectRackOrder(p, jp, u);
381  } while (jp.peek() == gx_system::JsonParser::value_key);
383  u.get_list(rack_units.mono, false, param);
384  u.get_list(rack_units.stereo, true, param);
385 }
386 
387 void PresetIO::write_parameters(gx_system::JsonWriter &w, bool preset) {
388  w.begin_object(true);
389 #if 0
390  int n = 0;
391  int pp = 1;
392  for (std::vector<std::string>::iterator j = mono_rack_units.begin(); j != mono_rack_units.end(); ++j) {
393  if (*j == "ampstack") {
394  n = 1;
395  pp = 0;
396  }
397  w.write_key("ui."+*j);
398  w.write(1);
399  w.write_key(*j+".pp");
400  w.write(pp);
401  w.write_key(*j+".position");
402  w.write(n);
403  n++;
404  }
405 #endif
406  for (gx_engine::ParamMap::iterator i = param.begin();
407  i != param.end(); ++i) {
408  gx_engine::Parameter *param = i->second;
409  if (!param->isSavable()) {
410  continue;
411  }
412  if ((preset and param->isInPreset()) or(!preset and !param->isInPreset())) {
413  param->writeJSON(w);
414  w.newline();
415  }
416  }
417  w.end_object(true);
418 }
419 
420 void PresetIO::read_intern(gx_system::JsonParser &jp, bool *has_midi, const gx_system::SettingsFileHeader& head) {
421  bool use_midi = (has_midi != 0) || midi_in_preset();
422  if (has_midi) {
423  *has_midi = false;
424  }
426  do {
428  if (jp.current_value() == "engine") {
429  read_parameters(jp, true);
430  } else if (jp.current_value() == "jconv") { // for backwards compatibility
431  dynamic_cast<gx_engine::JConvParameter*>(&param["jconv.convolver"])->readJSON_value(jp);
432  } else if (jp.current_value() == "midi_controller") {
433  if (use_midi) {
434  m = new gx_engine::ControllerArray();
435  m->readJSON(jp, param);
436  if (has_midi) {
437  *has_midi = true;
438  }
439  } else {
440  jp.skip_object();
441  }
442  } else {
444  _("recall settings"),
445  _("unknown preset section: ") + jp.current_value());
446  jp.skip_object();
447  }
448  } while (jp.peek() == gx_system::JsonParser::value_key);
450  fixup_parameters(head);
451 }
452 
454  for (gx_engine::paramlist::iterator i = plist.begin(); i != plist.end(); ++i) {
455  (*i)->setJSON_value();
456  }
457  if (m) {
458  mctrl.set_controller_array(*m);
459  }
460  clear();
461  mctrl.update_from_controllers();
462 }
463 
464 void PresetIO::write_intern(gx_system::JsonWriter &w, bool write_midi) {
465  w.begin_object(true);
466  w.write_key("engine");
467  write_parameters(w, true);
468  if (write_midi) {
469  w.write_key("midi_controller");
470  mctrl.writeJSON(w);
471  }
472  w.newline();
473  w.end_object(true);
474 }
475 
477  write_intern(jw, midi_in_preset());
478 }
479 
481  gx_system::JsonWriter &jw) {
482  param.set_init_values();
483  bool has_midi;
484  clear();
485  read_intern(jp, &has_midi, head);
486  commit_preset();
487  write_intern(jw, has_midi);
488 }
489 
490 
491 /****************************************************************
492  ** class StateIO
493  */
494 
497  gx_jack::GxJack& jack_, gx_system::CmdlineOptions& opt_, UnitRacks& rack_units)
498  : PresetIO(mctrl, cvr, param, opt_, rack_units),
499  midi_std_control(mstdctr),
500  jack(jack_) {
501 }
502 
504 }
505 
507  clear();
508  for (gx_engine::ParamMap::iterator i = param.begin(); i != param.end(); ++i) {
509  if (i->second->isSavable()) {
510  i->second->stdJSON_value();
511  plist.push_back(i->second);
512  }
513  }
514  do {
516  if (jp.current_value() == "settings") {
517  read_parameters(jp, false);
518  } else if (jp.current_value() == "current_preset") {
519  read_intern(jp, 0, head);
520  } else if (jp.current_value() == "midi_controller") {
521  m = new gx_engine::ControllerArray();
522  m->readJSON(jp, param);
523  } else if (jp.current_value() == "midi_ctrl_names") {
524  midi_std_control.readJSON(jp);
525  } else if (jp.current_value() == "jack_connections") {
526  jack.read_connections(jp);
527  } else {
529  _("recall settings"),
530  _("unknown section: ") + jp.current_value());
531  jp.skip_object();
532  }
533  } while (jp.peek() == gx_system::JsonParser::value_string);
534 }
535 
537  commit_preset();
538 }
539 
540 void StateIO::write_state(gx_system::JsonWriter &jw, bool no_preset) {
541  jw.write("settings");
542  write_parameters(jw, false);
543 
544  jw.write("midi_controller");
545  mctrl.writeJSON(jw);
546 
547  jw.write("midi_ctrl_names");
548  midi_std_control.writeJSON(jw);
549 
550  if (!no_preset) {
551  jw.write("current_preset");
552  write_intern(jw, false);
553  }
554 
555  jw.write("jack_connections");
556  jack.write_connections(jw);
557 
558  jw.newline();
559 }
560 
561 
562 /****************************************************************
563  ** class PluginPresetList
564  */
565 
568  : filename(fname), pmap(pmap_), mctrl(mctrl_), is(), jp(&is) {
569 }
570 
572  is.close();
573  is.open(filename.c_str());
574  jp.set_streampos(0);
575  if (is.fail()) {
576  return false;
577  }
578  try {
581  if (jp.current_value() != "gx_plugin_version") {
582  throw gx_system::JsonException("invalid gx_plugin file header");
583  }
585  } catch (gx_system::JsonException& e) {
586  gx_print_error(filename.c_str(), _("parse error"));
587  return false;
588  }
589  return true;
590 }
591 
592 bool PluginPresetList::next(Glib::ustring& name, bool *is_set) {
593  try {
595  name = "";
596  if (is_set) {
597  *is_set = false;
598  }
599  return false;
600  }
602  name = jp.current_value();
603  if (is_set) {
605  *is_set = true;
606  while (jp.peek() != gx_system::JsonParser::end_object) {
608  if (!pmap.hasId(jp.current_value())) {
610  _("recall plugin settings"),
611  _("unknown parameter: ")+jp.current_value());
612  jp.skip_object();
613  continue;
614  }
615  gx_engine::Parameter& p = pmap[jp.current_value()];
616  p.readJSON_value(jp);
617  if (!p.compareJSON_value()) {
618  *is_set = false;
619  }
620  }
622  } else {
623  jp.skip_object();
624  }
625  } catch (gx_system::JsonException& e) {
626  gx_print_error(filename.c_str(), _("parse error"));
627  return false;
628  }
629  return true;
630 }
631 
632 bool PluginPresetList::set(const Glib::ustring& name) {
633  gx_engine::paramlist plist;
634  if (!start()) {
635  return false;
636  }
637  bool ret = false;
638  try {
639  while (jp.peek() != gx_system::JsonParser::end_array) {
641  if (jp.current_value() != name) {
642  jp.skip_object();
643  } else {
644  ret = true;
646  while (jp.peek() != gx_system::JsonParser::end_object) {
648  if (pmap.hasId(jp.current_value())) {
649  gx_engine::Parameter& p = pmap[jp.current_value()];
650  p.readJSON_value(jp);
651  plist.push_back(&p);
652  }
653  }
655  }
656  }
659  } catch (gx_system::JsonException& e) {
660  gx_print_error(filename.c_str(), _("parse error"));
661  return false;
662  }
663  mctrl.remove_controlled_parameters(plist, 0);
664  for (gx_engine::paramlist::iterator i = plist.begin(); i != plist.end(); ++i) {
665  (*i)->setJSON_value();
666  }
667  return ret;
668 }
669 
670 static const int GX_PLUGIN_VERSION = 1;
671 
672 static inline bool compare_groups(const std::string& id, const char **groups) { //FIXME (is copy from gx_paramtable.cpp
673  if (!groups) {
674  return false;
675  }
676  for (const char **g = groups; *g; g += 2) {
677  const char *p = *g;
678  if ((*p) != '.') {
679  continue;
680  }
681  p++;
682  int n = strlen(p);
683  if (strncmp(id.c_str(), p, n) == 0 && id[n] == '.') {
684  return true;
685  }
686  }
687  return false;
688 }
689 
690 void PluginPresetList::write_values(gx_system::JsonWriter& jw, std::string id, const char **groups) {
691  id += ".";
692  string on_off = id + "on_off";
693  string pp = id + "pp";
694  std::string position = id + "position";
695  jw.begin_object(true);
696  for (gx_engine::ParamMap::iterator i = pmap.begin(); i != pmap.end(); ++i) {
697  if (i->first.compare(0, id.size(), id) == 0 || compare_groups(i->first, groups)) {
698  if (i->second->isInPreset()) {
699  if (i->first != on_off && i->first != pp && i->first != position) {
700  i->second->writeJSON(jw);
701  jw.newline();
702  }
703  }
704  }
705  }
706  jw.end_object(true);
707 }
708 
709 void PluginPresetList::save(const Glib::ustring& name, const std::string& id, const char **groups) {
710  try {
711  std::string tmpfile(filename + "_tmp");
712  ofstream os(tmpfile.c_str());
713  gx_system::JsonWriter jw(&os);
714  jw.begin_array();
715  jw.write("gx_plugin_version");
716  jw.write(GX_PLUGIN_VERSION, true);
717  bool found = false;
718  if (start()) {
719  while (jp.peek() != gx_system::JsonParser::end_array) {
721  jw.write(jp.current_value());
722  if (jp.current_value() == name) {
723  found = true;
724  write_values(jw, id, groups);
725  jp.skip_object();
726  } else {
727  jp.copy_object(jw);
728  }
729  }
730  }
731  if (!found) {
732  jw.write(name);
733  write_values(jw, id, groups);
734  }
735  jw.end_array(true);
736  jw.close();
737  os.close();
738  if (!os.good()) {
739  gx_print_error(_("save plugin preset"),
740  boost::format(_("couldn't write %1%")) % tmpfile);
741  return;
742  }
743  int rc = rename(tmpfile.c_str(), filename.c_str());
744  if (rc != 0) {
745  gx_print_error(_("save plugin preset"),
746  boost::format(_("couldn't rename %1% to %2%"))
747  % tmpfile % filename);
748  }
749  } catch (gx_system::JsonException& e) {
750  gx_print_error(filename.c_str(), _("parse error"));
751  }
752 }
753 
754 bool PluginPresetList::remove(const Glib::ustring& name) {
755  bool ret = false;
756  if (start()) {
757  try {
758  std::string tmpfile(filename + "_tmp");
759  ofstream os(tmpfile.c_str());
760  gx_system::JsonWriter jw(&os);
761  jw.begin_array();
762  jw.write("gx_plugin_version");
763  jw.write(GX_PLUGIN_VERSION, true);
764  while (jp.peek() != gx_system::JsonParser::end_array) {
766  if (jp.current_value() == name) {
767  jp.skip_object();
768  ret = true;
769  } else {
770  jw.write(jp.current_value());
771  jp.copy_object(jw);
772  }
773  }
776  jw.end_array(true);
777  jw.close();
778  os.close();
779  if (!os.good()) {
780  gx_print_error(_("remove plugin preset"),
781  boost::format(_("couldn't write %1%")) % tmpfile);
782  return false;
783  }
784  int rc = rename(tmpfile.c_str(), filename.c_str());
785  if (rc != 0) {
786  gx_print_error(_("remove plugin preset"),
787  boost::format(_("couldn't rename %1% to %2%"))
788  % tmpfile % filename);
789  return false;
790  }
791  } catch (gx_system::JsonException& e) {
792  gx_print_error(filename.c_str(), _("parse error"));
793  }
794  return ret;
795  } else {
796  return false;
797  }
798 }
799 
800 
801 /****************************************************************
802  ** GxSettings
803  */
804 
805 static const char *scratchpad_name = N_("Scratchpad");
806 static const char *scratchpad_file = "scratchpad.gx";
807 static const char *statename_postfix = "_rc";
808 static const char *bank_list = "banklist.js";
809 
813  : sigc::trackable(),
814  GxSettingsBase(seq_),
815  param(seq_.get_param()),
816  preset_io(mctrl_, cvr, param, opt, rack_units),
817  state_io(mctrl_, cvr, param, mstdctr, jack_, opt, rack_units),
818  state_loaded(false),
819  no_autosave(false),
820  jack(jack_),
821  mctrl(mctrl_),
822  options(opt),
823  preset_parameter(*param.reg_string("system.current_preset", "?", &current_name, "")),
824  bank_parameter(*param.reg_string("system.current_bank", "?", &current_bank, "")) {
825  set_io(&state_io, &preset_io);
826  statefile.set_filename(make_default_state_filename());
827  banks.parse(opt.get_preset_filepath(bank_list), opt.get_preset_dir(), opt.get_factory_dir(),
828  scratchpad_name, scratchpad_file);
829  instance = this;
830  GxExit::get_instance().signal_exit().connect(
831  sigc::mem_fun(*this, &GxSettings::exit_handler));
832  jack.signal_client_change().connect(
833  sigc::mem_fun(*this, &GxSettings::jack_client_changed));
834 }
835 
836 GxSettings *GxSettings::instance = 0;
837 
839  instance = 0;
840  auto_save_state();
841 }
842 
844  if (state_loaded) {
845  if (setting_is_preset()) {
848  !pf->get_flags()) {
849  save(*pf, current_name);
850  }
851  }
852  if (!no_autosave) {
853  save_to_state();
854  }
855  }
856 }
857 
858 void GxSettings::exit_handler(bool otherthread) {
859  if (otherthread) {
860  return;
861  }
862  auto_save_state();
863 }
864 
865 void GxSettings::jack_client_changed() {
866  string fn = make_state_filename();
867  if (state_loaded && fn == statefile.get_filename()) {
869  return;
870  }
871  if (!state_loaded && access(fn.c_str(), R_OK|W_OK) != 0) {
872  string defname = make_default_state_filename();
873  if (access(defname.c_str(), R_OK) == 0) {
874  statefile.set_filename(defname);
875  loadsetting(0, "");
876  }
877  }
879  loadstate();
880 }
881 
882 string GxSettings::make_default_state_filename() {
883  if (!options.get_loadfile().empty()) {
884  return options.get_loadfile();
885  }
886  std::string s = options.get_jack_instancename();
887  if (!s.empty()) {
888  s = options.get_user_filepath(s + statename_postfix);
889  if (access(s.c_str(), R_OK|W_OK) == 0) {
890  return s;
891  }
892  }
893  return options.get_user_filepath(
894  jack.get_default_instancename() + statename_postfix);
895 }
896 
897 string GxSettings::make_state_filename() {
898  if (!options.get_loadfile().empty()) {
899  return options.get_loadfile();
900  }
901  return options.get_user_filepath(
902  jack.get_instancename() + statename_postfix);
903 }
904 
905 bool GxSettings::check_create_config_dir(const Glib::ustring& dir) {
906  if (access((Glib::build_filename(dir, ".")).c_str(), R_OK|W_OK|X_OK) != 0) {
907  if (errno != ENOENT) {
908  throw GxFatalError(
909  boost::format(_("no read/write access in guitarix config dir '%1%'"))
910  % dir);
911  }
912  if (mkdir(dir.c_str(), 0777) != 0) {
913  throw GxFatalError(
914  boost::format(_("can't create guitarix config dir '%1%'"))
915  % dir);
916  }
917  return true;
918  }
919  return false;
920 }
921 
923  save(*banks.get_file(scratchpad_name), "livebuffer1");
924 }
925 
926 static inline std::vector<std::string>::iterator find_unit(std::vector<std::string>& r, const std::string& unit) {
927  std::vector<std::string>::iterator i = r.begin();
928  for (; i != r.end(); ++i) {
929  if (unit == *i) {
930  break;
931  }
932  }
933  return i;
934 }
935 
936 bool GxSettings::remove_rack_unit(const std::string& unit, bool stereo) {
937  std::vector<std::string>& r = stereo ? rack_units.stereo : rack_units.mono;
938  std::vector<std::string>::iterator i = find_unit(r, unit);
939  if (i != r.end()) {
940  r.erase(i);
941  return true;
942  }
943  return false;
944 }
945 
946 void GxSettings::insert_rack_unit(const std::string& unit, const std::string& before, bool stereo) {
947  std::vector<std::string>& r = stereo ? rack_units.stereo : rack_units.mono;
948  remove_rack_unit(unit, stereo);
949  if (before.empty()) {
950  r.push_back(unit);
951  } else {
952  r.insert(find_unit(r, before), unit);
953  }
954 }
955 
956 Glib::RefPtr<Gio::File> GxSettings::uri_to_name_filename(const Glib::ustring& uri, Glib::ustring& name, std::string& filename) {
957  Glib::RefPtr<Gio::File> rem = Gio::File::create_for_uri(uri);
958  filename = rem->get_basename();
959  banks.strip_preset_postfix(filename);
960  name = gx_system::decode_filename(filename);
961  banks.make_valid_utf8(name);
962  banks.make_bank_unique(name, &filename);
963  return rem;
964 }
965 
966 gx_system::PresetFile* GxSettings::bank_insert_uri(const Glib::ustring& uri, bool move) {
967  Glib::ustring name;
968  std::string filename;
969  Glib::RefPtr<Gio::File> rem = uri_to_name_filename(uri, name, filename);
970  Glib::RefPtr<Gio::File> dest = Gio::File::create_for_path(filename);
971  try {
972  rem->copy(dest);
973  } catch (Gio::Error& e) {
974  gx_print_error(e.what().c_str(), _("can't copy to config dir"));
975  return 0;
976  }
978  if (f->open_file(name, filename, gx_system::PresetFile::PRESET_FILE, 0)) {
979  banks.insert(f);
980  } else {
981  delete f;
982  try {
983  dest->remove();
984  } catch (Gio::Error& e) {
985  gx_print_error(e.what().c_str(), _("can't remove copied file!?"));
986  }
987  return 0;
988  }
989  if (move) {
990  try {
991  rem->remove();
992  } catch (Gio::Error& e) {
993  gx_print_error(e.what().c_str(), _("can't move; file has been copied"));
994  }
995  }
996  return f;
997 }
998 
999 gx_system::PresetFile* GxSettings::bank_insert_content(const Glib::ustring& uri, const std::string content) {
1000  Glib::ustring name;
1001  std::string filename;
1002  uri_to_name_filename(uri, name, filename);
1003  Glib::RefPtr<Gio::File> dest = Gio::File::create_for_path(filename);
1004  try {
1005  Glib::RefPtr<Gio::FileOutputStream> s = dest->create_file();
1006  s->write(content);
1007  s->close();
1008  } catch (Gio::Error& e) {
1009  gx_print_error(e.what().c_str(), _("can't bank"));
1010  return 0;
1011  }
1013  if (f->open_file(name, filename, gx_system::PresetFile::PRESET_FILE, 0)) {
1014  banks.insert(f);
1015  } else {
1016  delete f;
1017  try {
1018  dest->remove();
1019  } catch (Gio::Error& e) {
1020  gx_print_error(e.what().c_str(), _("can't remove copied file!?"));
1021  }
1022  return 0;
1023  }
1024  return f;
1025 }
1026 
1028  Glib::ustring newname = name;
1029  std::string newfile;
1030  banks.make_bank_unique(newname, &newfile);
1032  if (f->create_file(newname, newfile, gx_system::PresetFile::PRESET_FILE, 0)) {
1033  banks.insert(f);
1034  return f;
1035  } else {
1036  delete f;
1037  return 0;
1038  }
1039 }
1040 
1041 bool GxSettings::rename_bank(const Glib::ustring& oldname, Glib::ustring& newname) {
1042  std::string newfile;
1043  banks.make_bank_unique(newname, &newfile);
1044  return GxSettingsBase::rename_bank(oldname, newname, newfile);
1045 }
1046 
1047 //static
1049  bool copied_from_old = false;
1050  std::string oldpreset;
1051  *need_new_preset = false;
1052  if (check_create_config_dir(opt.get_user_dir())) {
1053  check_create_config_dir(opt.get_preset_dir());
1054  check_create_config_dir(opt.get_plugin_dir());
1055  check_create_config_dir(opt.get_pluginpreset_dir());
1056  check_create_config_dir(opt.get_lv2_preset_dir());
1057  check_create_config_dir(opt.get_loop_dir());
1058  check_create_config_dir(opt.get_user_IR_dir());
1059  check_create_config_dir(opt.get_temp_dir());
1060  std::string fname = gx_jack::GxJack::get_default_instancename() + statename_postfix;
1061  if (access(Glib::build_filename(opt.get_old_user_dir(), fname).c_str(), R_OK) == 0) {
1062  copied_from_old = true;
1063  Glib::RefPtr<Gio::File> f = Gio::File::create_for_path(
1064  Glib::build_filename(opt.get_old_user_dir(), fname));
1065  try {
1066  f->copy(Gio::File::create_for_path(opt.get_user_filepath(fname)));
1067  } catch (Gio::Error& e) {
1068  gx_print_error(e.what().c_str(), _("can't copy to new config dir"));
1069  }
1070  }
1071  fname = Glib::build_filename(
1072  opt.get_old_user_dir(),
1074  if (access(fname.c_str(), R_OK) == 0) {
1075  Glib::RefPtr<Gio::File> f = Gio::File::create_for_path(fname);
1076  oldpreset = opt.get_preset_filepath("oldpresets.gx");
1077  try {
1078  f->copy(Gio::File::create_for_path(oldpreset));
1079  } catch (Gio::Error& e) {
1080  gx_print_error(e.what().c_str(), _("can't copy to new config preset dir"));
1081  oldpreset = "";
1082  }
1083  }
1084  } else {
1085  check_create_config_dir(opt.get_preset_dir());
1086  check_create_config_dir(opt.get_plugin_dir());
1087  check_create_config_dir(opt.get_pluginpreset_dir());
1088  check_create_config_dir(opt.get_lv2_preset_dir());
1089  check_create_config_dir(opt.get_loop_dir());
1090  check_create_config_dir(opt.get_user_IR_dir());
1091  check_create_config_dir(opt.get_temp_dir());
1092  }
1093  std::string fname = opt.get_preset_filepath(scratchpad_file);
1094  if (access(fname.c_str(), R_OK) != 0) {
1096  throw GxFatalError(
1097  boost::format(_("can't create file in '%1%' !!??")) % opt.get_preset_dir());
1098  }
1099  *need_new_preset = true;
1100  }
1101  fname = opt.get_preset_filepath(bank_list);
1102  if (access(fname.c_str(), R_OK) != 0) {
1103  ofstream f(fname.c_str());
1104  if (!f.good()) {
1105  throw GxFatalError(
1106  boost::format(_("can't create '%1%' in directory '%2%'"))
1107  % bank_list % opt.get_preset_dir());
1108  }
1110  pre.open_file(scratchpad_name, opt.get_preset_filepath(scratchpad_file), gx_system::PresetFile::PRESET_SCRATCH, 0);
1111  gx_system::JsonWriter jw(&f);
1112  jw.begin_array(true);
1113  pre.writeJSON(jw);
1114  if (!oldpreset.empty() && pre.open_file("copied presets", oldpreset, gx_system::PresetFile::PRESET_FILE, 0)) {
1115  pre.writeJSON(jw);
1116  }
1117  jw.end_array(true);
1118  jw.close();
1119  f.close();
1120  }
1121  return copied_from_old;
1122 }
1123 
1125  GxSettingsBase::loadstate();
1126 #if 0
1127  /* This following code is commented out because
1128  **
1129  ** o its debatable which of state file or scratch preset should have
1130  ** priority in case both differ because 2 different instantiations
1131  ** accessed the same scratch preset but different statefiles.
1132  **
1133  ** o if the scratch preset has priority, the autosave function would
1134  ** have to save to statefile *and* scratch preset (in case of the
1135  ** current preset being a scratch preset).
1136  **
1137  ** As an aside: load_preset() would have to be changed to not save
1138  ** to the scratch preset before loading in the case that this code
1139  ** is activated.
1140  */
1141  if (setting_is_preset()) {
1143  if (pf && pf->get_type() == gx_system::PresetFile::PRESET_SCRATCH) {
1144  /* make sure we see the content of the scratchpad,
1145  ** not the state file (in case someone changed the
1146  ** scratchpad while working with a different state file)
1147  */
1149  }
1150  }
1151 #endif
1152  state_loaded = true;
1153 }
1154 
1155 void GxSettings::add_plugin_preset_list(gx_preset::PluginPresetList& l,
1156  UnitPresetList &presetnames) {
1157  if (l.start()) {
1158  Glib::ustring name;
1159  bool is_set;
1160  while (l.next(name, &is_set)) {
1161  presetnames.push_back(PluginPresetEntry(name, is_set));
1162  }
1163  }
1164 }
1165 
1167  PluginPresetList lv2sets(options.get_lv2_preset_filepath(pdef->id), param, mctrl);
1168  add_plugin_preset_list(lv2sets, presetnames);
1169  PluginPresetList user(options.get_pluginpreset_filepath(pdef->id, false), param, mctrl);
1170  add_plugin_preset_list(user, presetnames);
1171  presetnames.push_back(PluginPresetEntry("", false));
1172  PluginPresetList factory(options.get_pluginpreset_filepath(pdef->id, true), param, mctrl);
1173  add_plugin_preset_list(factory, presetnames);
1174 }
1175 
1176 void GxSettings::plugin_preset_list_set(const PluginDef *pdef, bool factory, const Glib::ustring& name) {
1177  if (!PluginPresetList(options.get_pluginpreset_filepath(pdef->id, factory), param, mctrl).set(name))
1178  PluginPresetList(options.get_lv2_preset_filepath(pdef->id), param, mctrl).set(name);
1179 }
1180 
1181 void GxSettings::plugin_preset_list_save(const PluginDef *pdef, const Glib::ustring& name) {
1182  PluginPresetList(options.get_pluginpreset_filepath(pdef->id, false), param, mctrl).save(name, pdef->id, pdef->groups);
1183 }
1184 
1185 void GxSettings::plugin_preset_list_remove(const PluginDef *pdef, const Glib::ustring& name) {
1186  // remove loop files when delete a plugin preset
1187  if(strcmp(pdef->id,"dubber")==0) {
1188  std::string pPath = options.get_loop_dir();
1189  pPath += name;
1190  std::remove((pPath + "1.wav").c_str());
1191  std::remove((pPath + "2.wav").c_str());
1192  std::remove((pPath + "3.wav").c_str());
1193  std::remove((pPath + "4.wav").c_str());
1194  }
1195  if (!PluginPresetList(options.get_pluginpreset_filepath(pdef->id, false), param, mctrl).remove(name))
1196  PluginPresetList(options.get_lv2_preset_filepath(pdef->id), param, mctrl).remove(name);
1197 }
1198 
1199 
1200 /* ----------------------------------------------------------------*/
1201 } /* end of gx_preset namespace */
void write_state(gx_system::JsonWriter &jw, bool preserve_preset)
Definition: gx_preset.cpp:540
void set_pp(const std::string &s, bool v)
Definition: gx_preset.h:60
gx_system::PresetFile * bank_insert_uri(const Glib::ustring &uri, bool move)
Definition: gx_preset.cpp:966
void set_io(AbstractStateIO *st, AbstractPresetIO *pr)
Definition: gx_json.h:473
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
Definition: gx_preset.h:127
void save(PresetFile &pf, const Glib::ustring &name)
Definition: gx_json.cpp:1877
PresetFile * get_current_bank_file()
Definition: gx_json.h:482
const std::string & get_preset_dir() const
Definition: gx_system.h:473
void set_show(const std::string &s, bool v)
Definition: gx_preset.h:57
void make_bank_unique(Glib::ustring &name, std::string *file=0)
Definition: gx_json.cpp:1458
bool remove_rack_unit(const std::string &unit, bool stereo)
Definition: gx_preset.cpp:936
std::ostream & get_ostream()
Definition: gx_json.h:208
std::string get_pluginpreset_filepath(const std::string &id, bool factory) const
Definition: gx_system.h:467
map< string, Parameter * >::const_iterator iterator
Definition: gx_parameter.h:531
list< Parameter * > paramlist
Definition: gx_parameter.h:219
void set_visible(const std::string &s, bool v)
Definition: gx_preset.h:58
void create_default_scratch_preset()
Definition: gx_preset.cpp:922
void insert(PresetFile *f)
Definition: gx_json.h:448
void end_array(bool nl=false)
Definition: gx_json.cpp:192
void set_streampos(streampos pos)
Definition: gx_json.cpp:571
const Glib::ustring & get_jack_instancename() const
Definition: gx_system.h:493
void read_connections(gx_system::JsonParser &jp)
Definition: gx_jack.cpp:158
void write_preset(gx_system::JsonWriter &jw)
Definition: gx_preset.cpp:476
void read_preset(gx_system::JsonParser &jp, const gx_system::SettingsFileHeader &)
Definition: gx_preset.cpp:71
std::vector< PluginPresetEntry > UnitPresetList
Definition: gx_preset.h:134
#define N_(String)
PresetIO(gx_engine::MidiControllerList &mctrl, gx_engine::ConvolverAdapter &cvr, gx_engine::ParamMap &param, gx_system::CmdlineOptions &opt, UnitRacks &rack_units)
Definition: gx_preset.cpp:37
sigc::signal< void > selection_changed
Definition: gx_json.h:468
virtual void readJSON_value(gx_system::JsonParser &jp)=0
PresetFile * get_file(const Glib::ustring &bank) const
Definition: gx_json.cpp:1623
void read_state(gx_system::JsonParser &jp, const gx_system::SettingsFileHeader &)
Definition: gx_preset.cpp:506
bool isSavable() const
Definition: gx_parameter.h:169
std::string get_lv2_preset_filepath(const std::string &id) const
Definition: gx_system.h:469
virtual void writeJSON(gx_system::JsonWriter &jw) const =0
bool rename_bank(const Glib::ustring &oldname, Glib::ustring &newname)
Definition: gx_preset.cpp:1041
std::vector< std::string > mono
Definition: gx_preset.h:38
iterator end() const
Definition: gx_parameter.h:533
int get_type() const
Definition: gx_json.h:361
const std::string & get_loop_dir() const
Definition: gx_system.h:476
void write_key(const char *p, bool nl=false)
Definition: gx_json.cpp:200
static bool check_settings_dir(gx_system::CmdlineOptions &opt, bool *need_new_preset)
Definition: gx_preset.cpp:1048
const char ** groups
Definition: gx_plugin.h:187
void save(const Glib::ustring &name, const std::string &id, const char **groups)
Definition: gx_preset.cpp:709
std::string decode_filename(const std::string &s)
Definition: gx_system.cpp:1034
virtual bool compareJSON_value()=0
void copy_preset(gx_system::JsonParser &jp, const gx_system::SettingsFileHeader &, gx_system::JsonWriter &jw)
Definition: gx_preset.cpp:480
bool open_file(const Glib::ustring &name, const std::string &path, int tp, int flags)
Definition: gx_json.cpp:980
void parse(const std::string &bank_path, const std::string &preset_dir, const std::string &factory_path, const char *scratchpad_name, const char *scratchpad_file)
Definition: gx_json.cpp:1424
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
static string get_default_instancename()
Definition: gx_jack.cpp:46
static bool make_empty_settingsfile(const string &name)
Definition: gx_json.cpp:684
gx_system::PresetFile * bank_insert_new(const Glib::ustring &name)
Definition: gx_preset.cpp:1027
static bool strip_preset_postfix(std::string &name)
Definition: gx_json.cpp:1450
void plugin_preset_list_load(const PluginDef *pdef, UnitPresetList &presetnames)
Definition: gx_preset.cpp:1166
bool remove(const Glib::ustring &name)
Definition: gx_preset.cpp:754
StateIO(gx_engine::MidiControllerList &mctrl, gx_engine::ConvolverAdapter &cvr, gx_engine::ParamMap &param, gx_engine::MidiStandardControllers &mstdctr, gx_jack::GxJack &jack, gx_system::CmdlineOptions &opt, UnitRacks &rack_units)
Definition: gx_preset.cpp:495
const char * id
Definition: gx_plugin.h:185
bool isFloat() const
Definition: gx_parameter.h:161
bool hasId(const string &id) const
Definition: gx_parameter.h:534
void plugin_preset_list_save(const PluginDef *pdef, const Glib::ustring &name)
Definition: gx_preset.cpp:1181
void set_filename(const string &fn)
Definition: gx_json.cpp:746
virtual void close()
Definition: gx_json.cpp:68
void insert_rack_unit(const std::string &unit, const std::string &before, bool stereo)
Definition: gx_preset.cpp:946
void write_connections(gx_system::JsonWriter &w)
Definition: gx_jack.cpp:218
std::vector< std::string > stereo
Definition: gx_preset.h:39
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
const std::string & get_pluginpreset_dir() const
Definition: gx_system.h:474
string get_filename() const
Definition: gx_json.h:268
bool next(Glib::ustring &name, bool *is_set=0)
Definition: gx_preset.cpp:592
static GxExit & get_instance()
Definition: gx_logging.cpp:205
bool isInPreset() const
Definition: gx_parameter.h:168
void load_preset(PresetFile *pf, const Glib::ustring &name)
Definition: gx_json.cpp:1756
void copy_object(JsonWriter &jw)
Definition: gx_json.cpp:580
UnitPositionID(const string &id_, const UnitPosition &u)
Definition: gx_preset.cpp:163
const std::string & get_factory_dir() const
Definition: gx_system.h:478
FloatParameter & getFloat()
Definition: gx_parameter.h:451
void gx_print_warning(const char *, const std::string &)
Definition: gx_logging.cpp:161
void set_position(const std::string &s, int v)
Definition: gx_preset.h:59
const std::string & get_temp_dir() const
Definition: gx_system.h:477
const std::string & get_old_user_dir() const
Definition: gx_system.h:471
sigc::signal< void, bool > & signal_exit()
Definition: gx_logging.h:116
const string & get_instancename()
Definition: gx_jack.h:201
void writeJSON(gx_system::JsonWriter &jw) const
std::string get_user_filepath(const std::string &basename) const
Definition: gx_system.h:371
Glib::ustring current_name
Definition: gx_json.h:466
string current_value() const
Definition: gx_json.h:143
iterator begin() const
Definition: gx_parameter.h:532
sigc::signal< void > & signal_client_change()
Definition: gx_jack.h:210
bool set(const Glib::ustring &name)
Definition: gx_preset.cpp:632
void readJSON(gx_system::JsonParser &jp)
Glib::ustring current_bank
Definition: gx_json.h:465
const std::string & get_lv2_preset_dir() const
Definition: gx_system.h:475
void plugin_preset_list_remove(const PluginDef *pdef, const Glib::ustring &name)
Definition: gx_preset.cpp:1185
GxSettings(gx_system::CmdlineOptions &opt, gx_jack::GxJack &jack, gx_engine::ConvolverAdapter &cvr, gx_engine::MidiStandardControllers &mstdctr, gx_engine::MidiControllerList &mctrl, gx_engine::ModuleSequencer &seq)
Definition: gx_preset.cpp:810
int get_flags() const
Definition: gx_json.h:358
const std::string & get_loadfile() const
Definition: gx_system.h:492
std::string get_preset_filepath(const std::string &basename) const
Definition: gx_system.h:463
const std::string & get_user_dir() const
Definition: gx_system.h:374
token next(token expect=no_token)
Definition: gx_json.cpp:496
PluginPresetList(const std::string &fname, gx_engine::ParamMap &pmap, gx_engine::MidiControllerList &mctrl_)
Definition: gx_preset.cpp:566
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
const string & id() const
Definition: gx_parameter.h:171
bool operator<(const UnitPositionID &v) const
Definition: gx_preset.cpp:160
static void make_valid_utf8(Glib::ustring &s)
Definition: gx_json.cpp:1435
void get_list(std::vector< std::string > &l, bool stereo, gx_engine::ParamMap &param)
Definition: gx_preset.cpp:169
Glib::RefPtr< Gio::File > uri_to_name_filename(const Glib::ustring &uri, Glib::ustring &name, std::string &filename)
Definition: gx_preset.cpp:956
const std::string & get_plugin_dir() const
Definition: gx_system.h:472
bool create_file(const Glib::ustring &name, const std::string &path, int tp, int flags)
Definition: gx_json.cpp:994
bool loadsetting(PresetFile *p, const Glib::ustring &name)
Definition: gx_json.cpp:1719
gx_system::PresetFile * bank_insert_content(const Glib::ustring &uri, const std::string content)
Definition: gx_preset.cpp:999
void convert_from_range(float low, float up)
void remove_controlled_parameters(paramlist &plist, const ControllerArray *m)
void end_object(bool nl=false)
Definition: gx_json.cpp:176
void save_to_state(bool preserve_preset=false)
Definition: gx_json.cpp:1816
void plugin_preset_list_set(const PluginDef *pdef, bool factory, const Glib::ustring &name)
Definition: gx_preset.cpp:1176
const std::string & get_user_IR_dir() const
Definition: gx_system.h:375