1 extern "C"
2 {
3 #include "frei0r.h"
4 }
5
6 #include <list>
7 #include <vector>
8 #include <string>
9 #include <iostream>
10
11
12 namespace frei0r
13 {
14 class fx;
15
16 // remember me
17 static std::string s_name;
18 static std::string s_author;
19 static std::string s_explanation;
20 static std::pair<int,int> s_version;
21 static unsigned int s_effect_type;
22 static unsigned int s_color_model;
23
24 static fx* (*s_build) (unsigned int, unsigned int);
25
26 struct param_info
27 {
param_infofrei0r::param_info28 param_info(const std::string& name, const std::string& desc, int type)
29 : m_name(name), m_desc(desc), m_type(type) {}
30
31 std::string m_name;
32 std::string m_desc;
33 int m_type;
34 };
35
36 static std::vector<param_info> s_params;
37
38
39 class fx
40 {
41 public:
42
43 unsigned int width;
44 unsigned int height;
45 unsigned int size; // = width * height
46 std::vector<void*> param_ptrs;
47
fx()48 fx()
49 {
50 s_params.clear(); // reinit static params
51 }
52
53 virtual unsigned int effect_type()=0;
54
register_param(f0r_param_color & p_loc,const std::string & name,const std::string & desc)55 void register_param(f0r_param_color& p_loc,
56 const std::string& name,
57 const std::string& desc)
58 {
59 param_ptrs.push_back(&p_loc);
60 s_params.push_back(param_info(name,desc,F0R_PARAM_COLOR));
61 }
62
register_param(double & p_loc,const std::string & name,const std::string & desc)63 void register_param(double& p_loc,
64 const std::string& name,
65 const std::string& desc)
66 {
67 param_ptrs.push_back(&p_loc);
68 s_params.push_back(param_info(name,desc,F0R_PARAM_DOUBLE));
69 }
70
register_param(bool & p_loc,const std::string & name,const std::string & desc)71 void register_param(bool& p_loc,
72 const std::string& name,
73 const std::string& desc)
74 {
75 param_ptrs.push_back(&p_loc);
76 s_params.push_back(param_info(name,desc,F0R_PARAM_BOOL));
77 }
78
register_param(f0r_param_position & p_loc,const std::string & name,const std::string & desc)79 void register_param(f0r_param_position& p_loc,
80 const std::string& name,
81 const std::string& desc)
82 {
83 param_ptrs.push_back(&p_loc);
84 s_params.push_back(param_info(name,desc,F0R_PARAM_POSITION));
85 }
86
register_param(std::string & p_loc,const std::string & name,const std::string & desc)87 void register_param(std::string& p_loc,
88 const std::string& name,
89 const std::string& desc)
90 {
91 param_ptrs.push_back(&p_loc);
92 s_params.push_back(param_info(name,desc,F0R_PARAM_STRING));
93 }
94
95
get_param_value(f0r_param_t param,int param_index)96 void get_param_value(f0r_param_t param, int param_index)
97 {
98 void* ptr = param_ptrs[param_index];
99
100 switch (s_params[param_index].m_type)
101 {
102 case F0R_PARAM_BOOL :
103 *static_cast<f0r_param_bool*>(param)
104 = *static_cast<f0r_param_bool*>(ptr) > 0.5 ? 1.0 : 0.0;
105 break;
106 case F0R_PARAM_DOUBLE:
107 *static_cast<f0r_param_double*>(param)
108 = *static_cast<f0r_param_double*>(ptr);
109 break;
110 case F0R_PARAM_COLOR:
111 *static_cast<f0r_param_color*>(param)
112 = *static_cast<f0r_param_color*>(ptr);
113 break;
114 case F0R_PARAM_POSITION:
115 *static_cast<f0r_param_position*>(param)
116 = *static_cast<f0r_param_position*>(ptr);
117 break;
118 case F0R_PARAM_STRING:
119 *static_cast<f0r_param_string*>(param)
120 = const_cast<f0r_param_string>(static_cast<std::string*>(ptr)->c_str());
121 break;
122 }
123 }
124
125
set_param_value(f0r_param_t param,int param_index)126 void set_param_value(f0r_param_t param, int param_index)
127 {
128 void* ptr = param_ptrs[param_index];
129
130 switch (s_params[param_index].m_type)
131 {
132 case F0R_PARAM_BOOL :
133 *static_cast<bool*>(ptr)
134 = (*static_cast<f0r_param_bool*>(param) > 0.5) ;
135 break;
136 case F0R_PARAM_DOUBLE:
137 *static_cast<f0r_param_double*>(ptr)
138 = *static_cast<f0r_param_double*>(param);
139 break;
140 case F0R_PARAM_COLOR:
141 *static_cast<f0r_param_color*>(ptr)
142 = *static_cast<f0r_param_color*>(param);
143 break;
144 case F0R_PARAM_POSITION:
145 *static_cast<f0r_param_position*>(ptr)
146 = *static_cast<f0r_param_position*>(param);
147 break;
148 case F0R_PARAM_STRING:
149 *static_cast<std::string*>(ptr)
150 = *static_cast<f0r_param_string*>(param);
151 break;
152 }
153
154 }
155
156 virtual void update(double time,
157 uint32_t* out,
158 const uint32_t* in1,
159 const uint32_t* in2,
160 const uint32_t* in3) = 0;
161
~fx()162 virtual ~fx()
163 {
164 }
165 };
166
167 class source : public fx
168 {
169 protected:
source()170 source() {}
171
172 public:
effect_type()173 virtual unsigned int effect_type(){ return F0R_PLUGIN_TYPE_SOURCE; }
174 virtual void update(double time, uint32_t* out) = 0;
175
176 private:
update(double time,uint32_t * out,const uint32_t * in1,const uint32_t * in2,const uint32_t * in3)177 virtual void update(double time,
178 uint32_t* out,
179 const uint32_t* in1,
180 const uint32_t* in2,
181 const uint32_t* in3) {
182 (void)in1; // unused
183 (void)in2; // unused
184 (void)in3; // unused
185 update(time, out);
186 }
187 };
188
189 class filter : public fx
190 {
191 protected:
filter()192 filter() {}
193
194 public:
effect_type()195 virtual unsigned int effect_type(){ return F0R_PLUGIN_TYPE_FILTER; }
196 virtual void update(double time, uint32_t* out, const uint32_t* in1) = 0;
197
198 private:
update(double time,uint32_t * out,const uint32_t * in1,const uint32_t * in2,const uint32_t * in3)199 virtual void update(double time,
200 uint32_t* out,
201 const uint32_t* in1,
202 const uint32_t* in2,
203 const uint32_t* in3) {
204 (void)in2; // unused
205 (void)in3; // unused
206 update(time, out, in1);
207 }
208 };
209
210 class mixer2 : public fx
211 {
212 protected:
mixer2()213 mixer2() {}
214
215 public:
effect_type()216 virtual unsigned int effect_type(){ return F0R_PLUGIN_TYPE_MIXER2; }
217 virtual void update(double time, uint32_t* out, const uint32_t* in1, const uint32_t* in2) = 0;
218
219 private:
update(double time,uint32_t * out,const uint32_t * in1,const uint32_t * in2,const uint32_t * in3)220 virtual void update(double time,
221 uint32_t* out,
222 const uint32_t* in1,
223 const uint32_t* in2,
224 const uint32_t* in3) {
225 (void)in3; // unused
226 update(time, out, in1, in2);
227 }
228 };
229
230
231 class mixer3 : public fx
232 {
233 protected:
mixer3()234 mixer3() {}
235
236 public:
effect_type()237 virtual unsigned int effect_type(){ return F0R_PLUGIN_TYPE_MIXER3; }
238 };
239
240
241 // register stuff
242 template<class T>
243 class construct
244 {
245 public:
construct(const std::string & name,const std::string & explanation,const std::string & author,const int & major_version,const int & minor_version,unsigned int color_model=F0R_COLOR_MODEL_BGRA8888)246 construct(const std::string& name,
247 const std::string& explanation,
248 const std::string& author,
249 const int& major_version,
250 const int& minor_version,
251 unsigned int color_model = F0R_COLOR_MODEL_BGRA8888)
252 {
253 T a(0,0);
254
255 s_name=name;
256 s_explanation=explanation;
257 s_author=author;
258 s_version=std::make_pair(major_version,minor_version);
259 s_build=build;
260
261 s_effect_type=a.effect_type();
262 s_color_model=color_model;
263 }
264
265 private:
build(unsigned int width,unsigned int height)266 static fx* build(unsigned int width, unsigned int height)
267 {
268 return new T(width,height);
269 }
270 };
271 }
272
273
274 // the exported frei0r functions
275
f0r_init()276 int f0r_init()
277 {
278 return 1;
279 }
280
f0r_deinit()281 void f0r_deinit()
282 {
283 }
284
f0r_get_plugin_info(f0r_plugin_info_t * info)285 void f0r_get_plugin_info(f0r_plugin_info_t* info)
286 {
287 info->name = frei0r::s_name.c_str();
288 info->author = frei0r::s_author.c_str();
289 info->plugin_type = frei0r::s_effect_type;
290 info->color_model = frei0r::s_color_model;
291 info->frei0r_version = FREI0R_MAJOR_VERSION;
292 info->major_version = frei0r::s_version.first;
293 info->minor_version = frei0r::s_version.second;
294 info->explanation = frei0r::s_explanation.c_str();
295 info->num_params = static_cast<int>(frei0r::s_params.size());
296 }
297
f0r_get_param_info(f0r_param_info_t * info,int param_index)298 void f0r_get_param_info(f0r_param_info_t* info, int param_index)
299 {
300 info->name=frei0r::s_params[param_index].m_name.c_str();
301 info->type=frei0r::s_params[param_index].m_type;
302 info->explanation=frei0r::s_params[param_index].m_desc.c_str();
303 }
304
f0r_construct(unsigned int width,unsigned int height)305 f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
306 {
307 frei0r::fx* nfx = frei0r::s_build(width, height);
308 nfx->width=width;
309 nfx->height=height;
310 nfx->size=width*height;
311 return nfx;
312 }
313
f0r_destruct(f0r_instance_t instance)314 void f0r_destruct(f0r_instance_t instance)
315 {
316 delete static_cast<frei0r::fx*>(instance);
317 }
318
f0r_set_param_value(f0r_instance_t instance,f0r_param_t param,int param_index)319 void f0r_set_param_value(f0r_instance_t instance,
320 f0r_param_t param, int param_index)
321 {
322 static_cast<frei0r::fx*>(instance)->set_param_value(param, param_index);
323 }
324
f0r_get_param_value(f0r_instance_t instance,f0r_param_t param,int param_index)325 void f0r_get_param_value(f0r_instance_t instance,
326 f0r_param_t param, int param_index)
327 {
328 static_cast<frei0r::fx*>(instance)->get_param_value(param, param_index);
329 }
330
f0r_update2(f0r_instance_t instance,double time,const uint32_t * inframe1,const uint32_t * inframe2,const uint32_t * inframe3,uint32_t * outframe)331 void f0r_update2(f0r_instance_t instance, double time,
332 const uint32_t* inframe1,
333 const uint32_t* inframe2,
334 const uint32_t* inframe3,
335 uint32_t* outframe)
336 {
337 static_cast<frei0r::fx*>(instance)->update(time,
338 outframe,
339 inframe1,
340 inframe2,
341 inframe3);
342 }
343
344 // compability for frei0r 1.0
f0r_update(f0r_instance_t instance,double time,const uint32_t * inframe,uint32_t * outframe)345 void f0r_update(f0r_instance_t instance,
346 double time, const uint32_t* inframe, uint32_t* outframe)
347 {
348 f0r_update2(instance, time, inframe, 0, 0, outframe);
349 }
350
351