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 // utility class
20 // FIXME should be moved somewhere else
21 struct stringcomp {
operatorstringcomp22     inline bool operator() (const char* lhs, const char* rhs) const {
23 	return strcmp(lhs, rhs) < 0;
24     }
25 };
26 
27 namespace gx_engine {
28 
29 class EngineControl;
30 
31 /****************************************************************
32  ** class Plugin
33  ** Defines audio processing module and variables for
34  ** user interface
35 */
36 
37 enum {			       // additional flags for PluginDef (used internally)
38     PGNI_DYN_POSITION = 0x10000, // plugin is part of dynamically ordered rack
39     PGNI_NOT_OWN      = 0x20000, // not owned by PluginList
40     PGNI_UI_REG       = 0x40000, // Plugin registered in user interface
41     PGNI_IS_LV2       = 0x80000, // Plugin is in LV2 format
42     PGNI_IS_LADSPA    = 0x100000, // Plugin is in LADSPA format
43 };
44 
45 class Plugin {
46 private:
47     PluginDef *pdef;
48     BoolParameter *p_box_visible; ///< In Rack: UI Interface Box visible
49     BoolParameter *p_plug_visible; ///< minibox visible (false: full box)
50     BoolParameter *p_on_off;	   ///< Audio Processing
51     IntParameter  *p_position; ///< Position in Rack / Audio Processing Chain
52     IntParameter  *p_effect_post_pre; ///< pre/post amp position (post = 0)
53     int pos_tmp;
54     void set_midi_on_off_blocked(bool v);
55 public:
get_pdef()56     PluginDef *get_pdef() { return pdef; }
set_pdef(PluginDef * p)57     void set_pdef(PluginDef *p) { pdef = p; }
58     enum { POST_WEIGHT = 2000 };
59     Plugin(PluginDef *pl=0);
60     Plugin(gx_system::JsonParser& jp, ParamMap& pmap);
61     void writeJSON(gx_system::JsonWriter& jw);
get_box_visible()62     bool get_box_visible() const { return p_box_visible && p_box_visible->get_value(); }
get_plug_visible()63     bool get_plug_visible() const { return p_plug_visible && p_plug_visible->get_value(); }
get_on_off()64     bool get_on_off() const { return p_on_off->get_value(); }
get_position()65     int get_position() const { return p_position->get_value(); }
get_effect_post_pre()66     int get_effect_post_pre() const { return p_effect_post_pre->get_value(); }
set_box_visible(bool v)67     void set_box_visible(bool v) const { if (p_box_visible) p_box_visible->set(v); }
set_plug_visible(bool v)68     void set_plug_visible(bool v) const { if (p_plug_visible) p_plug_visible->set(v); }
set_on_off(bool v)69     void set_on_off(bool v) const { p_on_off->set(v); }
set_position(int v)70     void set_position(int v) const { p_position->set(v); }
set_effect_post_pre(int v)71     void set_effect_post_pre(int v) const { p_effect_post_pre->set(v); }
id_box_visible()72     const std::string& id_box_visible() const { return p_box_visible->id(); }
id_plug_visible()73     const std::string& id_plug_visible() const { return p_plug_visible->id(); }
id_on_off()74     const std::string& id_on_off() const { return p_on_off->id(); }
id_position()75     const std::string& id_position() const { return p_position->id(); }
id_effect_post_pre()76     const std::string& id_effect_post_pre() const { return p_effect_post_pre->id(); }
position_weight()77     inline int position_weight() { return get_effect_post_pre() ? get_position() : get_position() + POST_WEIGHT; }
78     void register_vars(ParamMap& param, EngineControl& seq);
79     void copy_position(const Plugin& plugin);
80     friend class PluginListBase;
81     friend class PluginList;
82     friend void printlist(const char *title, const list<Plugin*>& modules, bool header);
83 };
84 
85 /****************************************************************
86  ** class UiBuilderBase
87  */
88 
89 class UiBuilderBase: public UiBuilder {
90 public:
91     virtual bool load(Plugin *p) = 0;
92 };
93 
94 /****************************************************************
95  ** class ParamRegImpl
96  */
97 
98 class ParamRegImpl: public ParamReg {
99 private:
100     static ParamMap *pmap;
101     static float *registerFloatVar_(
102 	const char* id, const char* name, const char* tp,
103 	const char* tooltip, float* var, float val,
104 	float low, float up, float step, const value_pair* values=0);
105     static int *registerIntVar_(
106 	const char* id, const char* name, const char* tp,
107 	const char* tooltip, int* var, int val,
108 	int low, int up, const value_pair* values=0);
109     static bool *registerBoolVar_(
110 	const char* id, const char* name, const char* tp,
111 	const char* tooltip, bool* var, bool val);
112 public:
113     ParamRegImpl(ParamMap* pm);
114 };
115 
116 /****************************************************************
117  ** class PluginList
118  ** container of plugins for all processing chains
119  */
120 
121 enum PluginPos { // where to add a plugin (per processing chain)
122     PLUGIN_POS_START,
123     PLUGIN_POS_RACK,
124     PLUGIN_POS_END		// keep last one
125 };
126 
127 typedef PluginDef *(*plugindef_creator)();
128 
129 class PluginListBase {
130 public:
131     typedef pair<const std::string, Plugin*> map_pair;
132     typedef map<const std::string, Plugin*> pluginmap;
133 protected:
134     enum PluginPosInternal {
135 	PLUGIN_POS_RACK_STEREO = PLUGIN_POS_END+1,
136 	PLUGIN_POS_COUNT		// keep last one
137     };
138     pluginmap pmap;
139     sigc::signal<void,const char*,bool> insert_remove;
140 public:
141     PluginListBase();
142     ~PluginListBase();
143     void cleanup();
144     Plugin *find_plugin(const std::string& id) const;
145     Plugin *lookup_plugin(const std::string& id) const;
146     void append_rack(UiBuilderBase& ui);
147     void writeJSON(gx_system::JsonWriter& jw);
148     void readJSON(gx_system::JsonParser& jp, ParamMap& pmap);
begin()149     pluginmap::iterator begin() { return pmap.begin(); }
end()150     pluginmap::iterator end() { return pmap.end(); }
151     int insert_plugin(Plugin *pvars);
152     void update_plugin(Plugin *pvars);
153     void delete_module(Plugin *pl);
154 };
155 
156 class PluginList: public PluginListBase {
157     EngineControl& seq;
158     int plugin_pos[PLUGIN_POS_COUNT];
159     int add_module(Plugin *pl, PluginPos pos, int flags);
160 public:
161     PluginList(EngineControl& seq);
162     ~PluginList();
163     void set_samplerate(int samplerate); // call set_samplerate of all plugins
164     int load_from_path(const string& path, PluginPos pos = PLUGIN_POS_RACK);
165     int load_library(const string& path, PluginPos pos = PLUGIN_POS_RACK);
166     int add(Plugin *pl, PluginPos pos, int flags);
167     Plugin *add(PluginDef *p, PluginPos pos = PLUGIN_POS_RACK, int flags=0);
168     int add(PluginDef **p, PluginPos pos = PLUGIN_POS_RACK, int flags=0);
169     int add(plugindef_creator *p, PluginPos pos = PLUGIN_POS_RACK, int flags=0);
170     int check_version(PluginDef *p);
171     void registerGroup(PluginDef *pd, ParameterGroups& groups);
172     void registerParameter(Plugin *pl, ParamMap& param, ParamRegImpl& preg);
173     void registerPlugin(Plugin *pl, ParamMap& param, ParameterGroups& groups);
174     void unregisterGroup(PluginDef *pd, ParameterGroups& groups);
175     void unregisterParameter(Plugin *pl, ParamMap& param);
176     void rescueParameter(Plugin *pl, ParamMap& param);
177     void unregisterPlugin(Plugin *pl, ParamMap& param, ParameterGroups& groups);
178     void registerAllPlugins(ParamMap& param, ParameterGroups& groups);
179     void ordered_mono_list(list<Plugin*>& mono, int mode);
180     void ordered_stereo_list(list<Plugin*>& stereo, int mode);
181     void ordered_list(list<Plugin*>& l, bool stereo, int flagmask, int flagvalue);
signal_insert_remove()182     sigc::signal<void,const char*,bool>& signal_insert_remove() { return insert_remove; }
183 #ifndef NDEBUG
184     void printlist(bool ordered = true);
185 #endif
186 };
187 
188 #ifndef NDEBUG
189 void printlist(const char *title, const list<Plugin*>& modules, bool header=true);
190 #else
191 inline void printlist(const char *, const list<Plugin*>&, bool=true) {}
192 #endif
193 
194 } // !namespace gx_engine
195