FAUST compiler  0.9.9.6b8
propagate.cpp
Go to the documentation of this file.
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 #include "propagate.hh"
25 #include "prim2.hh"
26 #include <assert.h>
27 #include "ppbox.hh"
28 #include "xtended.hh"
29 #include "labels.hh"
30 #include "Text.hh"
31 #include "ppsig.hh"
32 #include "names.hh"
33 
34 //extern bool gPrintDocSwitch;
35 //static siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig);
36 
37 
39 
45 
47 
49 siglist mix(const siglist& lsig, int nbus)
50 {
51  int nlines = (int)lsig.size();
52 
53  siglist dst(nbus);
54 
55  for (int b=0; b<nbus; b++) {
56  Tree t = (b<nlines) ? lsig[b] : sigInt(0);
57  for (int i=b+nbus; i<nlines; i+=nbus) {
58  t = sigAdd(t, lsig[i]);
59  }
60  dst[b] = t;
61  }
62  return dst;
63 }
64 
66 siglist split(const siglist& inputs, int nbus)
67 {
68  int nlines = (int)inputs.size();
69 
70  siglist outputs(nbus);
71 
72  for (int b=0; b<nbus; b++) {
73  outputs[b] = inputs[b % nlines];
74  }
75  return outputs;
76 }
77 
80 {
81  siglist l(n);
82  for (int i = 0; i < n; i++) l[i] = sigDelay0(sigProj(i, t));
83  return l;
84 }
85 
88 {
89  siglist l(n);
90  for (int i = 0; i < n; i++) l[i] = sigDelay1(sigProj(i, t));
91  return l;
92 }
93 
94 
97 {
98  siglist l(n);
99  for (int i = 0; i < n; i++) l[i] = sigInput(i);
100  return l;
101 }
102 
104 {
105  siglist l(1);
106  l[0] = t;
107  return l;
108 }
109 
110 siglist listRange(const siglist& l, int i, int j)
111 {
112  siglist r(j-i);
113  for (int x = i; x < j; x++) r[x-i] = l[x];
114  return r;
115 }
116 
117 siglist listConcat(const siglist& a, const siglist& b)
118 {
119  int n1 = (int)a.size();
120  int n2 = (int)b.size();
121  siglist r(n1+n2);
122 
123  for (int x=0; x<n1; x++) r[x] = a[x];
124  for (int x=0; x<n2; x++) r[x+n1] = b[x];
125  return r;
126 }
127 
132 {
133  int n = (int)a.size();
134  Tree t=nil;
135  while (n--) t = cons(a[n],t);
136  return t;
137 }
138 
143  {
144  r.clear();
145  while (!isNil(l)) { r.push_back(hd(l)); l = tl(l); }
146  }
147 
149 {
150  int n = (int)l.size();
151  siglist r(n);
152 
153  for(int i = 0; i<n; i++) r[i] = lift(l[i]);
154  return r;
155 }
156 
157 static int gDummyInput = 10000;
158 
175 static Node PROPAGATEPROPERTY(symbol("PropagateProperty"));
176 
182 void setPropagateProperty(Tree args, const siglist& lsig)
183 {
185 }
186 
187 
195 {
196  Tree value;
197  if (getProperty(args, tree(PROPAGATEPROPERTY), value)) {
198  treelist2siglist(value, lsig);
199  return true;
200  } else {
201  return false;
202  }
203 }
204 
205 
215 siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig);
216 
217 
227 siglist propagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
228 {
229  Tree args =tree(PROPAGATEPROPERTY,slotenv,path,box,listConvert(lsig));
230  siglist result;
231  if (! getPropagateProperty(args, result)) {
232  result = realPropagate (slotenv, path, box, lsig);
233  setPropagateProperty(args, result);
234  }
235  //cerr << "propagate in " << boxpp(box) << endl;
236  //for (int i=0; i<lsig.size(); i++) { cerr << " -> signal " << i << " : " << *(lsig[i]) << endl; }
237  //cerr << endl;
238  return result;
239 }
240 
241 
251 siglist realPropagate (Tree slotenv, Tree path, Tree box, const siglist& lsig)
252 {
253  int i;
254  double r;
255  prim0 p0;
256  prim1 p1;
257  prim2 p2;
258  prim3 p3;
259  prim4 p4;
260  prim5 p5;
261 
262  Tree t1, t2, ff, label, cur, min, max, step, type, name, file, slot, body;
263  tvec wf;
264 
265 
266  xtended* xt = (xtended*)getUserData(box);
267 
268  // Extended Primitives
269 
270  if (xt) {
271  assert(lsig.size() == xt->arity());
272  return makeList(xt->computeSigOutput(lsig));
273  }
274 
275  // Numbers and Constants
276 
277  else if (isBoxInt(box, &i)) {
278  assert(lsig.size()==0);
279  return makeList(sigInt(i));
280  }
281  else if (isBoxReal(box, &r)) {
282  assert(lsig.size()==0);
283  return makeList(sigReal(r));
284  }
285 
286  // A Waveform has two outputs it size and a period signal representing its content
287 
288  else if (isBoxWaveform(box)) {
289  assert(lsig.size()==0);
290  const tvec br = box->branches();
291  return listConcat(makeList(sigInt(br.size())), makeList(sigWaveform(br)));
292  }
293 
294  else if (isBoxFConst(box, type, name, file)) {
295  assert(lsig.size()==0);
296  return makeList(sigFConst(type, name, file));
297  }
298 
299  else if (isBoxFVar(box, type, name, file)) {
300  assert(lsig.size()==0);
301  return makeList(sigFVar(type, name, file));
302  }
303 
304  // Wire and Cut
305 
306  else if (isBoxCut(box)) {
307  assert(lsig.size()==1);
308  return siglist();
309  }
310 
311  else if (isBoxWire(box)) {
312  assert(lsig.size()==1);
313  return lsig;
314  }
315 
316  // Slots and Symbolic Boxes
317 
318  else if (isBoxSlot(box)) {
319  Tree sig;
320  assert(lsig.size()==0);
321  if (!searchEnv(box,sig,slotenv)) {
322  // test YO simplification des diagrames
323  //fprintf(stderr, "propagate : internal error (slot undefined)\n");
324  //exit(1);
325  sig = sigInput(++gDummyInput);
326  }
327  return makeList(sig);
328  }
329 
330  else if (isBoxSymbolic(box, slot, body)) {
331  assert(lsig.size()>0);
332  return propagate(pushEnv(slot,lsig[0],slotenv), path, body, listRange(lsig, 1, (int)lsig.size()));
333  }
334 
335  // Primitives
336 
337  else if (isBoxPrim0(box, &p0)) {
338  assert(lsig.size()==0);
339  return makeList( p0() );
340  }
341 
342  else if (isBoxPrim1(box, &p1)) {
343  assert(lsig.size()==1);
344  return makeList( p1(lsig[0]) );
345  }
346 
347  else if (isBoxPrim2(box, &p2)) {
348 // printf("prim2 recoit : "); print(lsig); printf("\n");
349  assert(lsig.size()==2);
350  return makeList( p2(lsig[0],lsig[1]) );
351  }
352 
353  else if (isBoxPrim3(box, &p3)) {
354  assert(lsig.size()==3);
355  return makeList( p3(lsig[0],lsig[1],lsig[2]) );
356  }
357 
358  else if (isBoxPrim4(box, &p4)) {
359  assert(lsig.size()==4);
360  return makeList( p4(lsig[0],lsig[1],lsig[2],lsig[3]) );
361  }
362 
363  else if (isBoxPrim5(box, &p5)) {
364  assert(lsig.size()==5);
365  return makeList( p5(lsig[0],lsig[1],lsig[2],lsig[3],lsig[4]) );
366  }
367 
368  else if (isBoxFFun(box, ff)) {
369  //cerr << "propagate en boxFFun of arity " << ffarity(ff) << endl;
370  assert(int(lsig.size())==ffarity(ff));
371  return makeList(sigFFun(ff, listConvert(lsig)));
372  }
373 
374  // User Interface Widgets
375 
376  else if (isBoxButton(box, label)) {
377  assert(lsig.size()==0);
378  return makeList(sigButton(normalizePath(cons(label, path))));
379  }
380 
381  else if (isBoxCheckbox(box, label)) {
382  assert(lsig.size()==0);
383  return makeList(sigCheckbox(normalizePath(cons(label, path))));
384  }
385 
386  else if (isBoxVSlider(box, label, cur, min, max, step)) {
387  assert(lsig.size()==0);
388  return makeList(sigVSlider(normalizePath(cons(label, path)), cur, min, max, step));
389  }
390 
391  else if (isBoxHSlider(box, label, cur, min, max, step)) {
392  assert(lsig.size()==0);
393  return makeList(sigHSlider(normalizePath(cons(label, path)), cur, min, max, step));
394  }
395 
396  else if (isBoxNumEntry(box, label, cur, min, max, step)) {
397  assert(lsig.size()==0);
398  return makeList(sigNumEntry(normalizePath(cons(label, path)), cur, min, max, step));
399  }
400 
401  else if (isBoxVBargraph(box, label, min, max)) {
402  assert(lsig.size()==1);
403  return makeList(sigVBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
404  }
405 
406  else if (isBoxHBargraph(box, label, min, max)) {
407  assert(lsig.size()==1);
408  return makeList(sigHBargraph(normalizePath(cons(label, path)), min, max, lsig[0]));
409  }
410 
411  // User Interface Groups
412 
413  else if (isBoxVGroup(box, label, t1)) {
414  return propagate(slotenv,cons(cons(tree(0),label), path), t1, lsig);
415  }
416 
417  else if (isBoxHGroup(box, label, t1)) {
418  return propagate(slotenv, cons(cons(tree(1),label), path), t1, lsig);
419  }
420 
421  else if (isBoxTGroup(box, label, t1)) {
422  return propagate(slotenv, cons(cons(tree(2),label), path), t1, lsig);
423  }
424 
425  // Block Diagram Composition Algebra
426 
427  else if (isBoxSeq(box, t1, t2)) {
428  int in1, out1, in2, out2;
429  getBoxType(t1, &in1, &out1);
430  getBoxType(t2, &in2, &out2);
431 
432  assert(out1==in2);
433 
434  if (out1 == in2) {
435  return propagate(slotenv, path, t2, propagate(slotenv, path,t1,lsig));
436  } else if (out1 > in2) {
437  siglist lr = propagate(slotenv, path, t1,lsig);
438  return listConcat(propagate(slotenv, path, t2, listRange(lr, 0, in2)), listRange(lr, in2, out1));
439  } else {
440  return propagate(slotenv, path, t2, listConcat( propagate(slotenv, path, t1, listRange(lsig,0,in1)), listRange(lsig,in1,in1+in2-out1) ) );
441  }
442  }
443 
444  else if (isBoxPar(box, t1, t2)) {
445  int in1, out1, in2, out2;
446  getBoxType(t1, &in1, &out1);
447  getBoxType(t2, &in2, &out2);
448 
449  return listConcat( propagate(slotenv, path, t1, listRange(lsig, 0, in1)),
450  propagate(slotenv, path, t2, listRange(lsig, in1, in1+in2)) );
451  }
452 
453  else if (isBoxSplit(box, t1, t2)) {
454  int in1, out1, in2, out2;
455  getBoxType(t1, &in1, &out1);
456  getBoxType(t2, &in2, &out2);
457 
458  siglist l1 = propagate(slotenv, path, t1, lsig);
459  siglist l2 = split(l1, in2);
460  return propagate(slotenv, path, t2, l2);
461  }
462 
463  else if (isBoxMerge(box, t1, t2)) {
464  int in1, out1, in2, out2;
465  getBoxType(t1, &in1, &out1);
466  getBoxType(t2, &in2, &out2);
467 
468  siglist l1 = propagate(slotenv, path, t1, lsig);
469  siglist l2 = mix(l1, in2);
470  return propagate(slotenv, path, t2, l2);
471  }
472 
473  else if (isBoxRec(box, t1, t2)) {
474  // Bug Corrected
475  int in1, out1, in2, out2;
476  getBoxType(t1, &in1, &out1);
477  getBoxType(t2, &in2, &out2);
478 
479  Tree slotenv2 = lift(slotenv); // the environment must also be lifted
480 
481  siglist l0 = makeMemSigProjList(ref(1), in2);
482  siglist l1 = propagate(slotenv2, path, t2, l0);
483  siglist l2 = propagate(slotenv2, path, t1, listConcat(l1,listLift(lsig)));
484  Tree g = rec(listConvert(l2));
485  return makeSigProjList(g, out1);
486  }
487 
488  cout << "ERROR in file " << __FILE__ << ':' << __LINE__ << ", unrecognised box expression : " << boxpp(box) << endl;
489  exit(1);
490  return siglist();
491 }
492 
501 Tree boxPropagateSig (Tree path, Tree box, const siglist& lsig)
502 {
503  return listConvert(propagate(nil, path, box, lsig));
504 }
505 
bool isBoxPrim1(Tree s)
Definition: boxes.cpp:315
bool isBoxPrim5(Tree s)
Definition: boxes.cpp:335
Tree(* prim2)(Tree x, Tree y)
Definition: boxes.hh:210
Tree pushEnv(Tree key, Tree val, Tree env)
Definition: list.cpp:351
bool isBoxWire(Tree t)
Definition: boxes.cpp:109
Tree sigReal(double r)
Definition: signals.cpp:43
bool searchEnv(Tree key, Tree &v, Tree env)
Definition: list.cpp:356
static Node PROPAGATEPROPERTY(symbol("PropagateProperty"))
Propagate computes the outputs signals of a block-diagram according to a list of input signals...
Tree sigDelay0(Tree t0)
Definition: signals.cpp:55
siglist listConcat(const siglist &a, const siglist &b)
Definition: propagate.cpp:117
bool isBoxSeq(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:136
siglist mix(const siglist &lsig, int nbus)
propagate : box listOfSignal-> listOfSignal'
Definition: propagate.cpp:49
Tree sigHBargraph(Tree lbl, Tree min, Tree max, Tree x)
Definition: signals.cpp:278
Tree sigHSlider(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: signals.cpp:215
bool isBoxInt(Tree t)
Definition: boxes.cpp:78
Class Node = (type x (int + double + Sym + void*))
Definition: node.hh:75
bool getPropagateProperty(Tree args, siglist &lsig)
Retreive the propagation result as a property of the arguments tuplet.
Definition: propagate.cpp:194
siglist makeList(Tree t)
Definition: propagate.cpp:103
siglist propagate(Tree slotenv, Tree path, Tree box, const siglist &lsig)
Propagate a list of signals into a block diagram.
Definition: propagate.cpp:227
Tree rec(Tree body)
create a de Bruijn recursive tree
Tree cons(Tree a, Tree b)
Definition: list.hh:124
bool isBoxSplit(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:148
Tree ref(int level)
create a de Bruijn recursive reference
Tree sigInput(int i)
Definition: signals.cpp:47
Tree(* prim4)(Tree w, Tree x, Tree y, Tree z)
Definition: boxes.hh:212
vector< Tree > tvec
Definition: tree.hh:90
bool isBoxFFun(Tree s)
Definition: boxes.cpp:344
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
bool isBoxCut(Tree t)
Definition: boxes.cpp:105
int ffarity(Tree t)
Definition: prim2.cpp:67
Tree hd(Tree l)
Definition: list.hh:133
bool isBoxPrim0(Tree s)
Definition: boxes.cpp:310
bool isBoxPrim4(Tree s)
Definition: boxes.cpp:330
bool isBoxHGroup(Tree s)
Definition: boxes.cpp:437
bool isBoxHBargraph(Tree s)
Definition: boxes.cpp:455
bool isBoxRec(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:144
double max(double x, double y)
Definition: interval.hh:60
siglist split(const siglist &inputs, int nbus)
split une liste de signaux sur n bus
Definition: propagate.cpp:66
Tree(* prim3)(Tree x, Tree y, Tree z)
Definition: boxes.hh:211
bool isNil(Tree l)
Definition: list.hh:137
Tree(* prim5)(Tree v, Tree w, Tree x, Tree y, Tree z)
Definition: boxes.hh:213
void setPropagateProperty(Tree args, const siglist &lsig)
Store the propagation result as a property of the arguments tuplet.
Definition: propagate.cpp:182
Tree sigVSlider(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: signals.cpp:235
bool isBoxSymbolic(Tree t)
Definition: boxes.cpp:126
bool isBoxTGroup(Tree s)
Definition: boxes.cpp:449
Tree boxPropagateSig(Tree path, Tree box, const siglist &lsig)
Top level propagate a list of signals into a block diagram.
Definition: propagate.cpp:501
Tree sigProj(int i, Tree rgroup)
Definition: signals.cpp:150
bool isBoxButton(Tree s)
Definition: boxes.cpp:366
bool isBoxReal(Tree t)
Definition: boxes.cpp:79
Tree(* prim1)(Tree x)
Definition: boxes.hh:209
Tree lift(Tree t)
Tree listConvert(const siglist &a)
Convert an stl list of signals into a tree list of signals.
Definition: propagate.cpp:131
bool isBoxPar(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:140
bool isBoxHSlider(Tree s)
Definition: boxes.cpp:379
void treelist2siglist(Tree l, siglist &r)
Convert a tree list of signals into an stl list of signals.
Definition: propagate.cpp:142
Tree sigWaveform(const tvec &wf)
Definition: signals.cpp:210
siglist listLift(const siglist &l)
Definition: propagate.cpp:148
bool isBoxVBargraph(Tree s)
Definition: boxes.cpp:461
bool isBoxWaveform(Tree s)
Definition: boxes.cpp:97
Tree sigAdd(Tree x, Tree y)
Definition: signals.hh:152
bool isBoxCheckbox(Tree s)
Definition: boxes.cpp:372
siglist makeMemSigProjList(Tree t, int n)
Fabrique une liste de n mem projections d'un groupe récursif.
Definition: propagate.cpp:87
siglist listRange(const siglist &l, int i, int j)
Definition: propagate.cpp:110
bool isBoxVGroup(Tree s)
Definition: boxes.cpp:443
virtual Tree computeSigOutput(const vector< Tree > &args)=0
virtual unsigned int arity()=0
siglist makeSigInputList(int n)
Fabrique une liste de n entrées.
Definition: propagate.cpp:96
bool isBoxFVar(Tree s)
Definition: boxes.cpp:356
const tvec & branches() const
return all branches (subtrees) of a tree
Definition: tree.hh:146
const char * name(Symbol *sym)
Returns the name of a symbol.
Definition: symbol.hh:98
Tree sigFFun(Tree ff, Tree largs)
Definition: signals.cpp:132
Tree sigFConst(Tree type, Tree name, Tree file)
Definition: signals.cpp:137
Tree tree(const Node &n)
Definition: tree.hh:186
Tree sigCheckbox(Tree lbl)
Definition: signals.cpp:204
Tree sigVBargraph(Tree lbl, Tree min, Tree max, Tree x)
Definition: signals.cpp:284
bool isBoxVSlider(Tree s)
Definition: boxes.cpp:399
Definition: ppbox.hh:58
bool isBoxNumEntry(Tree s)
Definition: boxes.cpp:418
void setProperty(Tree t, Tree key, Tree val)
Definition: list.cpp:418
bool isBoxSlot(Tree t)
Definition: boxes.cpp:119
Tree sigNumEntry(Tree lbl, Tree cur, Tree min, Tree max, Tree step)
Definition: signals.cpp:255
void * getUserData(Symbol *sym)
Returns user data.
Definition: symbol.hh:100
Tree sigFVar(Tree type, Tree name, Tree file)
Definition: signals.cpp:143
bool isBoxPrim3(Tree s)
Definition: boxes.cpp:325
Tree sigButton(Tree lbl)
Definition: signals.cpp:198
Tree nil
Definition: list.cpp:116
Symbol * symbol(const char *str)
Returns (and creates if new) the symbol of name str.
Definition: symbol.hh:95
Tree normalizePath(Tree path)
Definition: labels.cpp:133
static int gDummyInput
Definition: propagate.cpp:157
Interface for names management.
bool isBoxMerge(Tree t, Tree &x, Tree &y)
Definition: boxes.cpp:152
vector< Tree > siglist
Definition: propagate.hh:43
bool isBoxFConst(Tree s)
Definition: boxes.cpp:350
double min(double x, double y)
Definition: interval.hh:59
bool isBoxPrim2(Tree s)
Definition: boxes.cpp:320
Tree tl(Tree l)
Definition: list.hh:134
siglist realPropagate(Tree slotenv, Tree path, Tree box, const siglist &lsig)
Propagate a list of signals into a block diagram.
Definition: propagate.cpp:251
siglist makeSigProjList(Tree t, int n)
Fabrique une liste de n projections d'un groupe récursif.
Definition: propagate.cpp:79
Tree(* prim0)()
Definition: boxes.hh:208
bool getProperty(Tree t, Tree key, Tree &val)
Definition: list.cpp:423
bool getBoxType(Tree box, int *inum, int *onum)
Return the type (number of inputs and outputs) of a box or false if undefined.
Definition: boxtype.cpp:63
Tree sigDelay1(Tree t0)
Definition: signals.cpp:57
Tree sigInt(int i)
Signals.
Definition: signals.cpp:40