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