Refactoring of process classes in faustexp.ml.
[Faustine.git] / interpretor / faust-0.9.47mr3 / architecture / q.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST Architecture File
4 Copyright (C) 2006-2011 Albert Graef <Dr.Graef@t-online.de>
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20 ************************************************************************
21 ************************************************************************/
22
23 /* Q architecture file. Derived from minimal.cpp included in the Faust
24 distribution. Please note that this is to be compiled as a shared library,
25 which is then loaded dynamically by Q's faust module. */
26
27 #include <stdlib.h>
28 #include <math.h>
29
30 struct Meta
31 {
32 void declare (const char* key, const char* value) { }
33 };
34
35 //-------------------------------------------------------------------
36 // Generic min and max using c++ inline
37 //-------------------------------------------------------------------
38
39 inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
40 inline int max (int a, int b) { return (a>b) ? a : b; }
41
42 inline long max (long a, long b) { return (a>b) ? a : b; }
43 inline long max (int a, long b) { return (a>b) ? a : b; }
44 inline long max (long a, int b) { return (a>b) ? a : b; }
45
46 inline float max (float a, float b) { return (a>b) ? a : b; }
47 inline float max (int a, float b) { return (a>b) ? a : b; }
48 inline float max (float a, int b) { return (a>b) ? a : b; }
49 inline float max (long a, float b) { return (a>b) ? a : b; }
50 inline float max (float a, long b) { return (a>b) ? a : b; }
51
52 inline double max (double a, double b) { return (a>b) ? a : b; }
53 inline double max (int a, double b) { return (a>b) ? a : b; }
54 inline double max (double a, int b) { return (a>b) ? a : b; }
55 inline double max (long a, double b) { return (a>b) ? a : b; }
56 inline double max (double a, long b) { return (a>b) ? a : b; }
57 inline double max (float a, double b) { return (a>b) ? a : b; }
58 inline double max (double a, float b) { return (a>b) ? a : b; }
59
60
61 inline int min (int a, int b) { return (a<b) ? a : b; }
62
63 inline long min (long a, long b) { return (a<b) ? a : b; }
64 inline long min (int a, long b) { return (a<b) ? a : b; }
65 inline long min (long a, int b) { return (a<b) ? a : b; }
66
67 inline float min (float a, float b) { return (a<b) ? a : b; }
68 inline float min (int a, float b) { return (a<b) ? a : b; }
69 inline float min (float a, int b) { return (a<b) ? a : b; }
70 inline float min (long a, float b) { return (a<b) ? a : b; }
71 inline float min (float a, long b) { return (a<b) ? a : b; }
72
73 inline double min (double a, double b) { return (a<b) ? a : b; }
74 inline double min (int a, double b) { return (a<b) ? a : b; }
75 inline double min (double a, int b) { return (a<b) ? a : b; }
76 inline double min (long a, double b) { return (a<b) ? a : b; }
77 inline double min (double a, long b) { return (a<b) ? a : b; }
78 inline double min (float a, double b) { return (a<b) ? a : b; }
79 inline double min (double a, float b) { return (a<b) ? a : b; }
80
81 // abs is now predefined
82 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
83
84
85 inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
86
87 /******************************************************************************
88 *******************************************************************************
89
90 VECTOR INTRINSICS
91
92 *******************************************************************************
93 *******************************************************************************/
94
95 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
96 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
97
98 <<includeIntrinsic>>
99
100 /******************************************************************************
101 *******************************************************************************
102
103 ABSTRACT USER INTERFACE
104
105 *******************************************************************************
106 *******************************************************************************/
107
108 class UI
109 {
110 bool fStopped;
111 public:
112
113 UI() : fStopped(false) {}
114 virtual ~UI() {}
115
116 virtual void addButton(char* label, float* zone) = 0;
117 virtual void addToggleButton(char* label, float* zone) = 0;
118 virtual void addCheckButton(char* label, float* zone) = 0;
119 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
120 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
121 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
122
123 virtual void addNumDisplay(char* label, float* zone, int precision) = 0;
124 virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max) = 0;
125 virtual void addHorizontalBargraph(char* label, float* zone, float min, float max) = 0;
126 virtual void addVerticalBargraph(char* label, float* zone, float min, float max) = 0;
127
128 virtual void openFrameBox(char* label) = 0;
129 virtual void openTabBox(char* label) = 0;
130 virtual void openHorizontalBox(char* label) = 0;
131 virtual void openVerticalBox(char* label) = 0;
132 virtual void closeBox() = 0;
133
134 virtual void run() = 0;
135
136 void stop() { fStopped = true; }
137 bool stopped() { return fStopped; }
138
139 virtual void declare(float* zone, const char* key, const char* value) {}
140 };
141
142 /***************************************************************************
143 Q UI interface
144 ***************************************************************************/
145
146 enum ui_elem_type_t {
147 UI_BUTTON, UI_TOGGLE_BUTTON, UI_CHECK_BUTTON,
148 UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
149 UI_V_BARGRAPH, UI_H_BARGRAPH,
150 UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
151 };
152
153 struct ui_elem_t {
154 ui_elem_type_t type;
155 char *label;
156 float *zone;
157 void *ref;
158 float init, min, max, step;
159 };
160
161 class QUI : public UI
162 {
163 public:
164 int nelems;
165 ui_elem_t *elems;
166
167 QUI();
168 virtual ~QUI();
169
170 protected:
171 void add_elem(ui_elem_type_t type, char *label = NULL);
172 void add_elem(ui_elem_type_t type, char *label, float *zone);
173 void add_elem(ui_elem_type_t type, char *label, float *zone,
174 float init, float min, float max, float step);
175 void add_elem(ui_elem_type_t type, char *label, float *zone,
176 float min, float max);
177
178 public:
179 virtual void addButton(char* label, float* zone);
180 virtual void addToggleButton(char* label, float* zone);
181 virtual void addCheckButton(char* label, float* zone);
182 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step);
183 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step);
184 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step);
185
186 virtual void addNumDisplay(char* label, float* zone, int precision);
187 virtual void addTextDisplay(char* label, float* zone, char* names[], float min, float max);
188 virtual void addHorizontalBargraph(char* label, float* zone, float min, float max);
189 virtual void addVerticalBargraph(char* label, float* zone, float min, float max);
190
191 virtual void openFrameBox(char* label);
192 virtual void openTabBox(char* label);
193 virtual void openHorizontalBox(char* label);
194 virtual void openVerticalBox(char* label);
195 virtual void closeBox();
196
197 virtual void run();
198 };
199
200 QUI::QUI()
201 {
202 nelems = 0;
203 elems = NULL;
204 }
205
206 QUI::~QUI()
207 {
208 if (elems) free(elems);
209 }
210
211 inline void QUI::add_elem(ui_elem_type_t type, char *label)
212 {
213 ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
214 if (elems1)
215 elems = elems1;
216 else
217 return;
218 elems[nelems].type = type;
219 elems[nelems].label = label;
220 elems[nelems].zone = NULL;
221 elems[nelems].ref = NULL;
222 elems[nelems].init = 0.0;
223 elems[nelems].min = 0.0;
224 elems[nelems].max = 0.0;
225 elems[nelems].step = 0.0;
226 nelems++;
227 }
228
229 inline void QUI::add_elem(ui_elem_type_t type, char *label, float *zone)
230 {
231 ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
232 if (elems1)
233 elems = elems1;
234 else
235 return;
236 elems[nelems].type = type;
237 elems[nelems].label = label;
238 elems[nelems].zone = zone;
239 elems[nelems].ref = NULL;
240 elems[nelems].init = 0.0;
241 elems[nelems].min = 0.0;
242 elems[nelems].max = 0.0;
243 elems[nelems].step = 0.0;
244 nelems++;
245 }
246
247 inline void QUI::add_elem(ui_elem_type_t type, char *label, float *zone,
248 float init, float min, float max, float step)
249 {
250 ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
251 if (elems1)
252 elems = elems1;
253 else
254 return;
255 elems[nelems].type = type;
256 elems[nelems].label = label;
257 elems[nelems].zone = zone;
258 elems[nelems].ref = NULL;
259 elems[nelems].init = init;
260 elems[nelems].min = min;
261 elems[nelems].max = max;
262 elems[nelems].step = step;
263 nelems++;
264 }
265
266 inline void QUI::add_elem(ui_elem_type_t type, char *label, float *zone,
267 float min, float max)
268 {
269 ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
270 if (elems1)
271 elems = elems1;
272 else
273 return;
274 elems[nelems].type = type;
275 elems[nelems].label = label;
276 elems[nelems].zone = zone;
277 elems[nelems].ref = NULL;
278 elems[nelems].init = 0.0;
279 elems[nelems].min = min;
280 elems[nelems].max = max;
281 elems[nelems].step = 0.0;
282 nelems++;
283 }
284
285 void QUI::addButton(char* label, float* zone)
286 { add_elem(UI_BUTTON, label, zone); }
287 void QUI::addToggleButton(char* label, float* zone)
288 { add_elem(UI_TOGGLE_BUTTON, label, zone); }
289 void QUI::addCheckButton(char* label, float* zone)
290 { add_elem(UI_CHECK_BUTTON, label, zone); }
291 void QUI::addVerticalSlider(char* label, float* zone, float init, float min, float max, float step)
292 { add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
293 void QUI::addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step)
294 { add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
295 void QUI::addNumEntry(char* label, float* zone, float init, float min, float max, float step)
296 { add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
297
298 // FIXME: addNumDisplay and addTextDisplay not implemented in Faust yet?
299 void QUI::addNumDisplay(char* label, float* zone, int precision) {}
300 void QUI::addTextDisplay(char* label, float* zone, char* names[], float min, float max) {}
301 void QUI::addHorizontalBargraph(char* label, float* zone, float min, float max)
302 { add_elem(UI_H_BARGRAPH, label, zone, min, max); }
303 void QUI::addVerticalBargraph(char* label, float* zone, float min, float max)
304 { add_elem(UI_V_BARGRAPH, label, zone, min, max); }
305
306 void QUI::openFrameBox(char* label) {}
307 void QUI::openTabBox(char* label)
308 { add_elem(UI_T_GROUP, label); }
309 void QUI::openHorizontalBox(char* label)
310 { add_elem(UI_H_GROUP, label); }
311 void QUI::openVerticalBox(char* label)
312 { add_elem(UI_V_GROUP, label); }
313 void QUI::closeBox()
314 { add_elem(UI_END_GROUP); }
315
316 void QUI::run() {}
317
318 /******************************************************************************
319 *******************************************************************************
320
321 FAUST DSP
322
323 *******************************************************************************
324 *******************************************************************************/
325
326
327
328 //----------------------------------------------------------------
329 // abstract definition of a signal processor
330 //----------------------------------------------------------------
331
332 class dsp {
333 protected:
334 int fSamplingFreq;
335 public:
336 dsp() {}
337 virtual ~dsp() {}
338 virtual int getNumInputs() = 0;
339 virtual int getNumOutputs() = 0;
340 virtual void buildUserInterface(UI* interface) = 0;
341 virtual void init(int samplingRate) = 0;
342 virtual void compute(int len, float** inputs, float** outputs) = 0;
343 };
344
345 //----------------------------------------------------------------------------
346 // FAUST generated signal processor
347 //----------------------------------------------------------------------------
348
349
350 <<includeclass>>
351
352 /* The class factory, used to create and destroy mydsp objects in the
353 client. Implemented using C linkage to facilitate dlopen access. */
354
355 extern "C" dsp *newdsp()
356 {
357 mydsp *d = new mydsp();
358 return d;
359 }
360
361 extern "C" void deldsp(dsp* d)
362 {
363 delete d;
364 }