Merge branch 'libsndfile'
[Faustine.git] / interpretor / preprocessor / faust-0.9.47mr3 / compiler / signals / signals.cpp
1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (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 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22
23 /*****************************************************************************
24 HISTORY
25 22/01/05 : added int cast in select2 and select3 selection signal
26 *****************************************************************************/
27
28
29
30 #include "signals.hh"
31
32
33 ////////////////////////////////////////////////////////////////////////
34 /**
35 * Signals
36 *
37 */
38 ///////////////////////////////////////////////////////////////////////
39
40 Tree sigInt(int i) { return tree(i); }
41 bool isSigInt(Tree t, int* i) { return isInt(t->node(), i); }
42
43 Tree sigReal(double r) { return tree(r); }
44 bool isSigReal(Tree t, double* r) { return isDouble(t->node(), r); }
45
46 Sym SIGINPUT = symbol ("sigInput");
47 Tree sigInput(int i) { return tree(SIGINPUT, tree(i)); }
48 bool isSigInput(Tree t, int* i) { Tree x; return isTree(t, SIGINPUT, x) && isInt(x->node(),i); }
49
50 Sym SIGOUTPUT = symbol ("sigOutput");
51 Tree sigOutput(int i, Tree t0) { return tree(SIGOUTPUT, tree(i), t0); }
52 bool isSigOutput(Tree t, int* i, Tree& t0) { Tree x; return isTree(t, SIGOUTPUT, x, t0) && isInt(x->node(),i); }
53
54 Sym SIGDELAY1 = symbol ("sigDelay1");
55 Tree sigDelay0(Tree t0) { return sigFixDelay(t0, sigInt(0));}
56
57 Tree sigDelay1(Tree t0) { return tree(SIGDELAY1, t0); }
58 bool isSigDelay1(Tree t, Tree& t0) { return isTree(t, SIGDELAY1, t0); }
59
60 Sym SIGFIXDELAY = symbol ("sigFixDelay");
61 Tree sigFixDelay(Tree t0, Tree t1) { return tree(SIGFIXDELAY, t0, sigIntCast(t1)); }
62 bool isSigFixDelay(Tree t, Tree& t0, Tree& t1) { return isTree(t, SIGFIXDELAY, t0, t1); }
63
64 Sym SIGPREFIX = symbol ("sigPrefix");
65 Tree sigPrefix(Tree t0, Tree t1) { return tree(SIGPREFIX, t0, t1); }
66 bool isSigPrefix(Tree t, Tree& t0, Tree& t1) { return isTree(t, SIGPREFIX, t0, t1); }
67
68 Sym SIGIOTA = symbol ("sigIota");
69 Tree sigIota(Tree t0) { return tree(SIGIOTA, t0); }
70 bool isSigIota(Tree t, Tree& t0) { return isTree(t, SIGIOTA, t0); }
71
72
73 // Read only and read write tables
74
75 Sym SIGRDTBL = symbol ("SigRDTbl");
76 Tree sigRDTbl (Tree t, Tree i) { return tree(SIGRDTBL, t, i); }
77 bool isSigRDTbl (Tree s, Tree& t, Tree& i) { return isTree(s, SIGRDTBL, t, i); }
78
79 Sym SIGWRTBL = symbol ("SigWRTbl");
80 Tree sigWRTbl (Tree id, Tree t, Tree i, Tree s) { return tree(SIGWRTBL, id, t, i, s); }
81 bool isSigWRTbl (Tree u, Tree& id, Tree& t, Tree& i, Tree& s) { return isTree(u, SIGWRTBL, id, t, i, s); }
82
83 Sym SIGTABLE = symbol ("SigTable");
84 Tree sigTable (Tree id, Tree n, Tree sig) { return tree(SIGTABLE, id, n, sig); }
85 bool isSigTable (Tree t, Tree& id, Tree& n, Tree& sig) { return isTree(t, SIGTABLE, id, n, sig); }
86
87 // Signal used to generate the initial content of a table
88
89 Sym SIGGEN = symbol ("SigGen");
90 Tree sigGen (Tree s) { return tree(SIGGEN, s); }
91 bool isSigGen (Tree t, Tree& x) { return isTree(t, SIGGEN, x); }
92 bool isSigGen (Tree t) { return t->node()== Node(SIGGEN); }
93
94
95 // Documentator Tables : special version of tables only for documentation purposes
96
97 Sym SIGDOCONSTANTTBL = symbol ("SigDocConstantTbl");
98 Tree sigDocConstantTbl (Tree n, Tree sig) { return tree(SIGDOCONSTANTTBL, n, sig); }
99 bool isSigDocConstantTbl (Tree t, Tree& n, Tree& sig) { return isTree(t, SIGDOCONSTANTTBL, n, sig); }
100
101 Sym SIGDOCWRITETBL = symbol ("SigDocWriteTbl");
102 Tree sigDocWriteTbl (Tree n, Tree sig, Tree widx, Tree wsig) { return tree(SIGDOCWRITETBL, n, sig, widx, wsig); }
103 bool isSigDocWriteTbl (Tree t, Tree& n, Tree& sig, Tree& widx, Tree& wsig) { return isTree(t, SIGDOCWRITETBL, n, sig, widx, wsig); }
104
105 Sym SIGDOCACCESSTBL = symbol ("SigDocAccessTbl");
106 Tree sigDocAccessTbl (Tree tbl, Tree ridx) { return tree(SIGDOCACCESSTBL, tbl, ridx); }
107 bool isSigDocAccessTbl (Tree t, Tree& tbl, Tree& ridx) { return isTree(t, SIGDOCACCESSTBL, tbl, ridx); }
108
109
110 // Select on signal among severals
111
112 Sym SIGSELECT2 = symbol ("SigSelect2");
113 Sym SIGSELECT3 = symbol ("SigSelect3");
114
115 Tree sigSelect2 (Tree selector, Tree s1, Tree s2) { return tree(SIGSELECT2, sigIntCast(selector), s1, s2); }
116 bool isSigSelect2 (Tree t, Tree& selector, Tree& s1, Tree& s2) { return isTree(t, SIGSELECT2, selector, s1, s2); }
117
118 Tree sigSelect3 (Tree selector, Tree s1, Tree s2, Tree s3) { return tree(SIGSELECT3, sigIntCast(selector), s1, s2, s3); }
119 bool isSigSelect3 (Tree t, Tree& selector, Tree& s1, Tree& s2, Tree& s3) { return isTree(t, SIGSELECT3, selector, s1, s2, s3); }
120
121
122 // multirate
123
124 Sym SIGVECTORIZE = symbol ("SigVectorize");
125 Tree sigVectorize (Tree n, Tree s) { return tree(SIGVECTORIZE, n, s); }
126 bool isSigVectorize (Tree a, Tree& n, Tree& s) { return isTree(a, SIGVECTORIZE, n, s); }
127
128 Sym SIGSERIALIZE = symbol ("SigSerialize");
129 Tree sigSerialize (Tree s1) { return tree(SIGSERIALIZE, s1); }
130 bool isSigSerialize (Tree a, Tree& s1) { return isTree(a, SIGSERIALIZE, s1); }
131
132 Sym SIGCONCAT = symbol ("SigConcat");
133 Tree sigConcat (Tree s1, Tree s2) { return tree(SIGCONCAT, s1, s2); }
134 bool isSigConcat (Tree a, Tree& s1, Tree& s2) { return isTree(a, SIGCONCAT, s1, s2); }
135
136 Sym SIGVECTORAT = symbol ("SigVectorAt");
137 Tree sigVectorAt (Tree s1, Tree s2) { return tree(SIGVECTORAT, s1, s2); }
138 bool isSigVectorAt(Tree a, Tree& s1, Tree& s2) { return isTree(a, SIGVECTORAT, s1, s2); }
139
140 Sym SIGUPSAMPLE = symbol ("SigUpsample");
141 Tree sigUpSample (Tree n, Tree s) { return tree(SIGUPSAMPLE, n, s); }
142 bool isSigUpSample (Tree a, Tree& n, Tree& s) { return isTree(a, SIGUPSAMPLE, n, s); }
143
144 Sym SIGDOWNSAMPLE = symbol ("SigDownsample");
145 Tree sigDownSample (Tree n, Tree s) { return tree(SIGDOWNSAMPLE, n, s); }
146 bool isSigDownSample (Tree a, Tree& n, Tree& s) { return isTree(a, SIGDOWNSAMPLE, n, s); }
147
148
149 // Arithmetical operations
150
151 Sym SIGBINOP = symbol ("SigBinOp");
152 Tree sigBinOp(int op, Tree x, Tree y) { return tree(SIGBINOP, tree(op), x, y); }
153 bool isSigBinOp(Tree s, int* op, Tree& x, Tree& y) { Tree t; return isTree(s, SIGBINOP, t, x, y) && isInt(t->node(),op); }
154
155
156 // Foreign Functions
157
158 Sym SIGFFUN = symbol ("SigFFun");
159 Tree sigFFun (Tree ff, Tree largs) { return tree(SIGFFUN, ff, largs); }
160 bool isSigFFun (Tree s, Tree& ff, Tree& largs) { return isTree(s, SIGFFUN, ff, largs); }
161
162
163 Sym SIGFCONST = symbol ("SigFConst");
164 Tree sigFConst (Tree type, Tree name, Tree file) { return tree(SIGFCONST, type, name, file); }
165 bool isSigFConst (Tree s) { Tree t,n,f; return isTree(s, SIGFCONST, t, n, f); }
166 bool isSigFConst (Tree s, Tree& type, Tree& name, Tree& file) { return isTree(s, SIGFCONST,type, name, file); }
167
168
169 Sym SIGFVAR = symbol ("SigFVar");
170 Tree sigFVar (Tree type, Tree name, Tree file) { return tree(SIGFVAR, type, name, file); }
171 bool isSigFVar (Tree s) { Tree t,n,f; return isTree(s, SIGFVAR, t, n, f); }
172 bool isSigFVar (Tree s, Tree& type, Tree& name, Tree& file) { return isTree(s, SIGFVAR, type, name, file); }
173
174 // nouvelle version utilisant rec et ref
175
176 Sym SIGPROJ = symbol ("SigProj");
177 Tree sigProj (int i, Tree rgroup) { return tree(SIGPROJ, tree(i), rgroup); }
178 bool isProj (Tree t, int* i, Tree& rgroup) { Tree x; return isTree(t, SIGPROJ, x, rgroup) && isInt(x->node(), i); }
179
180
181 // Int and Float casting
182
183 Sym SIGINTCAST = symbol ("sigIntCast");
184 Sym SIGFLOATCAST = symbol ("sigFloatCast");
185
186 Tree sigIntCast(Tree t)
187 {
188 Node n = t->node();
189
190 int i; if (isInt(n, &i)) return t;
191 double x; if (isDouble(n, &x)) return tree(int(x));
192 if (isSigIntCast(t)) return t;
193
194 return tree(SIGINTCAST, t);
195 }
196
197 Tree sigFloatCast(Tree t)
198 {
199 Node n = t->node();
200
201 int i; if (isInt(n, &i)) return tree(double(i));
202 double x; if (isDouble(n, &x)) return t;
203 if (isSigFloatCast(t)) return t;
204 if (isSigInput(t, &i)) return t;
205
206 return tree(SIGFLOATCAST, t);
207 }
208
209 //Tree sigFloatCast(Tree t) { return isSigFloatCast(t)? t : tree(SIGFLOATCAST, t); }
210
211 bool isSigIntCast(Tree t) { Tree x; return isTree(t, SIGINTCAST, x); }
212 bool isSigIntCast(Tree t, Tree& x) { return isTree(t, SIGINTCAST, x); }
213
214 bool isSigFloatCast(Tree t) { Tree x; return isTree(t, SIGFLOATCAST, x);}
215 bool isSigFloatCast(Tree t, Tree& x) { return isTree(t, SIGFLOATCAST, x); }
216
217
218
219
220 /*****************************************************************************
221 User Interface Elements
222 *****************************************************************************/
223
224 Sym SIGBUTTON = symbol ("SigButton");
225 Tree sigButton (Tree lbl) { return tree(SIGBUTTON, lbl); }
226 bool isSigButton (Tree s) { Tree lbl; return isTree(s, SIGBUTTON, lbl); }
227 bool isSigButton (Tree s, Tree& lbl) { return isTree(s, SIGBUTTON, lbl); }
228
229
230 Sym SIGCHECKBOX = symbol ("SigCheckbox");
231 Tree sigCheckbox (Tree lbl) { return tree(SIGCHECKBOX, lbl); }
232 bool isSigCheckbox (Tree s) { Tree lbl; return isTree(s, SIGCHECKBOX, lbl); }
233 bool isSigCheckbox (Tree s, Tree& lbl) { return isTree(s, SIGCHECKBOX, lbl); }
234
235
236 Sym SIGHSLIDER = symbol ("SigHSlider");
237 Tree sigHSlider (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
238 { return tree(SIGHSLIDER, lbl, list4(cur,min,max,step)); }
239 bool isSigHSlider (Tree s) { Tree lbl, params; return isTree(s, SIGHSLIDER, lbl, params); }
240
241 bool isSigHSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
242 {
243 Tree params;
244 if (isTree(s, SIGHSLIDER, lbl, params)) {
245 cur = nth(params, 0);
246 min = nth(params, 1);
247 max = nth(params, 2);
248 step= nth(params, 3);
249 return true;
250 } else {
251 return false;
252 }
253 }
254
255
256 Sym SIGVSLIDER = symbol ("SigVSlider");
257 Tree sigVSlider (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
258 { return tree(SIGVSLIDER, lbl, list4(cur,min,max,step)); }
259 bool isSigVSlider (Tree s) { Tree lbl, params; return isTree(s, SIGVSLIDER, lbl, params); }
260
261 bool isSigVSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
262 {
263 Tree params;
264 if (isTree(s, SIGVSLIDER, lbl, params)) {
265 cur = nth(params, 0);
266 min = nth(params, 1);
267 max = nth(params, 2);
268 step= nth(params, 3);
269 return true;
270 } else {
271 return false;
272 }
273 }
274
275
276 Sym SIGNUMENTRY = symbol ("SigNumEntry");
277 Tree sigNumEntry (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
278 { return tree(SIGNUMENTRY, lbl, list4(cur,min,max,step)); }
279 bool isSigNumEntry (Tree s) { Tree lbl, params; return isTree(s, SIGNUMENTRY, lbl, params); }
280
281 bool isSigNumEntry (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
282 {
283 Tree params;
284 if (isTree(s, SIGNUMENTRY, lbl, params)) {
285 cur = nth(params, 0);
286 min = nth(params, 1);
287 max = nth(params, 2);
288 step= nth(params, 3);
289 return true;
290 } else {
291 return false;
292 }
293 }
294
295 // output elements
296
297
298
299 Sym SIGHBARGRAPH = symbol ("SigHBargraph");
300 Tree sigHBargraph (Tree lbl, Tree min, Tree max, Tree x) { return tree(SIGHBARGRAPH, lbl, min, max, x); }
301 bool isSigHBargraph (Tree s) { Tree lbl, min, max, x; return isTree(s, SIGHBARGRAPH, lbl, min, max, x); }
302 bool isSigHBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x) { return isTree(s, SIGHBARGRAPH, lbl, min, max, x); }
303
304
305 Sym SIGVBARGRAPH = symbol ("SigVBargraph");
306 Tree sigVBargraph (Tree lbl, Tree min, Tree max, Tree x) { return tree(SIGVBARGRAPH, lbl, min, max, x); }
307 bool isSigVBargraph (Tree s) { Tree lbl, min, max, x; return isTree(s, SIGVBARGRAPH, lbl, min, max, x); }
308 bool isSigVBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x) { return isTree(s, SIGVBARGRAPH, lbl, min, max, x); }
309
310
311 Sym SIGATTACH = symbol ("sigAttach");
312 Tree sigAttach(Tree t0, Tree t1) { return tree(SIGATTACH, t0, t1); }
313 bool isSigAttach(Tree t, Tree& t0, Tree& t1) { return isTree(t, SIGATTACH, t0, t1); }
314
315
316
317 Tree addNums(Tree a, Tree b)
318 {
319 Tree r = tree(addNode(a->node(),b->node()));
320 //cerr.flags(ios::showpoint); cerr << "addNums " << *a << "+" << *b << " -> " << *r << endl;
321 return r;
322 }
323
324 Tree subNums(Tree a, Tree b)
325 {
326 Tree r = tree(subNode(a->node(),b->node()));
327 //cerr.flags(ios::showpoint); cerr << "subNums " << *a << "-" << *b << " -> " << *r << endl;
328 return r;
329 }
330
331 Tree mulNums(Tree a, Tree b)
332 {
333 Tree r = tree(mulNode(a->node(),b->node()));
334 //cerr.flags(ios::showpoint); cerr << "mulNums " << *a << "*" << *b << " -> " << *r << endl;
335 return r;
336 }
337
338 Tree divNums(Tree a, Tree b)
339 {
340 Tree r = tree(divNode(a->node(),b->node()));
341 //cerr.flags(ios::showpoint); cerr << "divNums " << *a << "/" << *b << " -> " << *r << endl;
342 return r;
343 }
344
345 Tree divExtendedNums(Tree a, Tree b)
346 {
347 Tree r = tree(divExtendedNode(a->node(),b->node()));
348 //cerr.flags(ios::showpoint); cerr << "divExtendeNums " << *a << "/" << *b << " -> " << *r << endl;
349 return r;
350 }
351
352 Tree minusNum(Tree a)
353 {
354 Tree r = tree(minusNode(a->node()));
355 //cerr.flags(ios::showpoint); cerr << "minusNum " << *a << " -> " << *r << endl;
356 return r;
357 }
358
359 Tree inverseNum(Tree a)
360 {
361 Tree r = tree(inverseNode(a->node()));
362 //cerr.flags(ios::showpoint); cerr << "inverseNum " << *a << " -> " << *r << endl;
363 return r;
364 }
365
366 bool isSigAdd(Tree a, Tree& x, Tree& y)
367 {
368 int op;
369 return isSigBinOp(a, &op, x, y) && (op == kAdd);
370 }
371
372 bool isSigMul(Tree a, Tree& x, Tree& y)
373 {
374 int op;
375 return isSigBinOp(a, &op, x, y) && (op == kMul);
376 }
377
378 bool isSigSub(Tree a, Tree& x, Tree& y)
379 {
380 int op;
381 return isSigBinOp(a, &op, x, y) && (op == kSub);
382 }
383
384 bool isSigDiv(Tree a, Tree& x, Tree& y)
385 {
386 int op;
387 return isSigBinOp(a, &op, x, y) && (op == kDiv);
388 }
389
390
391
392
393 /*****************************************************************************
394 matrix extension
395 *****************************************************************************/
396 Sym SIGTUPLE = symbol ("SigTuple");
397 Sym SIGTUPLEACCESS = symbol ("SigTupleAccess");
398
399 // a tuple of signals is basically a list of signals.
400 // mode = 0 means normal, mode = 1 means blocked
401 Tree sigTuple (int mode, Tree ls) { return tree(SIGTUPLE, tree(mode), ls); }
402 bool isSigTuple (Tree s, int* mode, Tree& ls) { Tree m; return isTree(s, SIGTUPLE, m, ls) && isInt(m->node(), mode); }
403
404 // Access the components of a tuple.
405 // ts is tuple of signals, idx is a scalar signal between 0..n
406 Tree sigTupleAccess(Tree ts, Tree idx) { return tree(SIGTUPLEACCESS, ts, idx); }
407 bool isSigTupleAccess(Tree s, Tree& ts, Tree& idx) { return isTree(s, SIGTUPLEACCESS, ts, idx); }
408
409 // create a tuple of signals
410 Tree sigCartesianProd (Tree s1, Tree s2)
411 {
412 Tree l1, l2;
413 int m1, m2;
414
415 if (isSigTuple(s1, &m1, l1) && (m1 == 0)) {
416 // nothing to do
417 } else {
418 l1 = list1(s1);
419 }
420
421 if (isSigTuple(s2, &m2, l2) && (m2 == 0)) {
422 // nothing to do
423 } else {
424 l2 = list1(s2);
425 }
426
427
428 return sigTuple(0, concat(l1,l2));
429 }
430
431
432
433 /**
434 * Test if exp is very simple that is it
435 * can't be considered a real component
436 * @param exp the signal we want to test
437 * @return true if it a very simple signal
438 */
439 bool verySimple(Tree exp)
440 {
441 int i;
442 double r;
443 Tree type, name, file;
444
445 return isSigInt(exp, &i)
446 || isSigReal(exp, &r)
447 || isSigInput(exp, &i)
448 || isSigFConst(exp, type, name, file);
449 }