FAUST compiler  0.9.9.6b8
signals.cpp
Go to the documentation of this file.
00001 /************************************************************************
00002  ************************************************************************
00003     FAUST compiler
00004     Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
00005     ---------------------------------------------------------------------
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  ************************************************************************
00020  ************************************************************************/
00021 
00022 
00023 /*****************************************************************************
00024     HISTORY
00025     22/01/05 : added int cast in select2 and select3 selection signal
00026 *****************************************************************************/
00027 
00028 
00029 
00030 #include "signals.hh"
00031 
00032 
00034 
00038 
00039 
00040 Tree  sigInt(int i)                                 { return tree(i);                   }
00041 bool  isSigInt(Tree t, int* i)                      { return isInt(t->node(), i);       }
00042 
00043 Tree  sigReal(double r)                             { return tree(r);                   }
00044 bool  isSigReal(Tree t, double* r)                  { return isDouble(t->node(), r);    }
00045 
00046 Sym SIGINPUT = symbol ("sigInput");
00047 Tree  sigInput(int i)                               { return tree(SIGINPUT, tree(i));   }
00048 bool  isSigInput(Tree t, int* i)                    { Tree x; return isTree(t, SIGINPUT, x) && isInt(x->node(),i);  }
00049 
00050 Sym SIGOUTPUT = symbol ("sigOutput");
00051 Tree  sigOutput(int i, Tree t0)                     { return tree(SIGOUTPUT, tree(i), t0);  }
00052 bool  isSigOutput(Tree t, int* i, Tree& t0)         { Tree x; return isTree(t, SIGOUTPUT, x, t0) && isInt(x->node(),i);     }
00053 
00054 Sym SIGDELAY1 = symbol ("sigDelay1");
00055 Tree  sigDelay0(Tree t0)                            { return sigFixDelay(t0, sigInt(0));}
00056 
00057 Tree  sigDelay1(Tree t0)                            { return tree(SIGDELAY1, t0);       }
00058 bool  isSigDelay1(Tree t, Tree& t0)                 { return isTree(t, SIGDELAY1, t0);  }
00059 
00060 Sym SIGFIXDELAY = symbol ("sigFixDelay");
00061 Tree  sigFixDelay(Tree t0, Tree t1)                 { return tree(SIGFIXDELAY, t0, sigIntCast(t1));         }
00062 bool  isSigFixDelay(Tree t, Tree& t0, Tree& t1)     { return isTree(t, SIGFIXDELAY, t0, t1);    }
00063 
00064 Sym SIGPREFIX = symbol ("sigPrefix");
00065 Tree  sigPrefix(Tree t0, Tree t1)                   { return tree(SIGPREFIX, t0, t1);       }
00066 bool  isSigPrefix(Tree t, Tree& t0, Tree& t1)       { return isTree(t, SIGPREFIX, t0, t1);  }
00067 
00068 Sym SIGIOTA = symbol ("sigIota");
00069 Tree  sigIota(Tree t0)                              { return tree(SIGIOTA, t0);         }
00070 bool  isSigIota(Tree t, Tree& t0)                   { return isTree(t, SIGIOTA, t0);    }
00071 
00072 
00073 // Read only and read write tables
00074 
00075 Sym SIGRDTBL = symbol ("SigRDTbl");
00076 Tree sigRDTbl (Tree t, Tree i)                      { return tree(SIGRDTBL, t, i);  }
00077 bool isSigRDTbl (Tree s, Tree& t, Tree& i)          { return isTree(s, SIGRDTBL, t, i);     }
00078 
00079 Sym SIGWRTBL = symbol ("SigWRTbl");
00080 Tree sigWRTbl (Tree id, Tree t, Tree i, Tree s)                 { return tree(SIGWRTBL, id, t, i, s);   }
00081 bool isSigWRTbl (Tree u, Tree& id, Tree& t, Tree& i, Tree& s)   { return isTree(u, SIGWRTBL, id, t, i, s);  }
00082 
00083 Sym SIGTABLE = symbol ("SigTable");
00084 Tree sigTable (Tree id, Tree n, Tree sig)               { return tree(SIGTABLE, id, n, sig);        }
00085 bool isSigTable (Tree t, Tree& id, Tree& n, Tree& sig)  { return isTree(t, SIGTABLE, id, n, sig);   }
00086 
00087 // Signal used to generate the initial content of a table
00088 
00089 Sym SIGGEN = symbol ("SigGen");
00090 Tree sigGen (Tree s)                            { return tree(SIGGEN, s);       }
00091 bool isSigGen (Tree t, Tree& x)                 { return isTree(t, SIGGEN, x);  }
00092 bool isSigGen (Tree t)                          { return t->node()== Node(SIGGEN);  }
00093 
00094 
00095 // Documentator Tables : special version of tables only for documentation purposes
00096 
00097 Sym SIGDOCONSTANTTBL = symbol ("SigDocConstantTbl");
00098 Tree   sigDocConstantTbl    (Tree n, Tree sig)                  { return tree(SIGDOCONSTANTTBL, n, sig);        }
00099 bool isSigDocConstantTbl    (Tree t, Tree& n, Tree& sig)        { return isTree(t, SIGDOCONSTANTTBL, n, sig);   }
00100 
00101 Sym SIGDOCWRITETBL = symbol ("SigDocWriteTbl");
00102 Tree   sigDocWriteTbl   (Tree n, Tree sig, Tree widx, Tree wsig)                { return tree(SIGDOCWRITETBL, n, sig, widx, wsig);      }
00103 bool isSigDocWriteTbl   (Tree t, Tree& n, Tree& sig, Tree& widx, Tree& wsig)    { return isTree(t, SIGDOCWRITETBL, n, sig, widx, wsig);     }
00104 
00105 Sym SIGDOCACCESSTBL = symbol ("SigDocAccessTbl");
00106 Tree   sigDocAccessTbl   (Tree tbl, Tree ridx)                  { return tree(SIGDOCACCESSTBL, tbl, ridx);      }
00107 bool isSigDocAccessTbl   (Tree t, Tree& tbl, Tree& ridx)        { return isTree(t, SIGDOCACCESSTBL, tbl, ridx);     }
00108 
00109 
00110 // Select on signal among severals
00111 
00112 Sym SIGSELECT2 = symbol ("SigSelect2");
00113 Sym SIGSELECT3 = symbol ("SigSelect3");
00114 
00115 Tree sigSelect2 (Tree selector, Tree s1, Tree s2)                           { return tree(SIGSELECT2, sigIntCast(selector), s1, s2); }
00116 bool isSigSelect2 (Tree t, Tree& selector, Tree& s1, Tree& s2)              { return isTree(t, SIGSELECT2, selector, s1, s2); }
00117 
00118 Tree sigSelect3 (Tree selector, Tree s1, Tree s2, Tree s3)                  { return tree(SIGSELECT3, sigIntCast(selector), s1, s2, s3); }
00119 bool isSigSelect3 (Tree t, Tree& selector, Tree& s1, Tree& s2, Tree& s3)    { return isTree(t, SIGSELECT3, selector, s1, s2, s3); }
00120 
00121 
00122 // Arithmetical operations
00123 
00124 Sym SIGBINOP = symbol ("SigBinOp");
00125 Tree sigBinOp(int op, Tree x, Tree y)                   { return tree(SIGBINOP, tree(op), x, y); }
00126 bool isSigBinOp(Tree s, int* op, Tree& x, Tree& y)      { Tree t; return isTree(s, SIGBINOP, t, x, y) && isInt(t->node(),op); }
00127 
00128 
00129 // Foreign Functions
00130 
00131 Sym SIGFFUN = symbol ("SigFFun");
00132 Tree sigFFun (Tree ff, Tree largs)                      { return tree(SIGFFUN, ff, largs);          }
00133 bool isSigFFun  (Tree s, Tree& ff, Tree& largs)         { return isTree(s, SIGFFUN, ff, largs);     }
00134 
00135 
00136 Sym SIGFCONST = symbol ("SigFConst");
00137 Tree sigFConst      (Tree type, Tree name, Tree file)             { return tree(SIGFCONST, type, name, file);         }
00138 bool isSigFConst    (Tree s)                                      { Tree t,n,f; return isTree(s, SIGFCONST, t, n, f); }
00139 bool isSigFConst    (Tree s, Tree& type, Tree& name, Tree& file)  { return isTree(s, SIGFCONST,type, name, file);     }
00140 
00141 
00142 Sym SIGFVAR = symbol ("SigFVar");
00143 Tree sigFVar      (Tree type, Tree name, Tree file)               { return tree(SIGFVAR, type, name, file);           }
00144 bool isSigFVar    (Tree s)                                        { Tree t,n,f; return isTree(s, SIGFVAR, t, n, f);   }
00145 bool isSigFVar    (Tree s, Tree& type, Tree& name, Tree& file)    { return isTree(s, SIGFVAR, type, name, file);      }
00146 
00147 // nouvelle version utilisant rec et ref
00148 
00149 Sym SIGPROJ = symbol ("SigProj");
00150 Tree sigProj (int i, Tree rgroup)               { return tree(SIGPROJ, tree(i), rgroup);    }
00151 bool isProj (Tree t, int* i, Tree& rgroup)      { Tree x; return isTree(t, SIGPROJ, x, rgroup) && isInt(x->node(), i);  }
00152 
00153 
00154 // Int and Float casting
00155 
00156 Sym SIGINTCAST = symbol ("sigIntCast");
00157 Sym SIGFLOATCAST = symbol ("sigFloatCast");
00158 
00159 Tree  sigIntCast(Tree t)                        
00160 { 
00161     Node n = t->node();
00162     
00163     int i;      if (isInt(n, &i))           return t; 
00164     double x;   if (isDouble(n, &x))        return tree(int(x));
00165                 if (isSigIntCast(t))        return t;
00166      
00167     return tree(SIGINTCAST, t);   
00168 }
00169 
00170 Tree  sigFloatCast(Tree t)                      
00171 { 
00172     Node n = t->node();
00173     
00174     int i;      if (isInt(n, &i))           return tree(double(i)); 
00175     double x;   if (isDouble(n, &x))        return t;
00176                 if (isSigFloatCast(t))      return t;
00177                 if (isSigInput(t, &i))      return t;
00178      
00179     return tree(SIGFLOATCAST, t);   
00180 }
00181 
00182 //Tree  sigFloatCast(Tree t)                        { return isSigFloatCast(t)? t : tree(SIGFLOATCAST, t); }
00183 
00184 bool  isSigIntCast(Tree t)                      { Tree x; return isTree(t, SIGINTCAST, x);  }
00185 bool  isSigIntCast(Tree t, Tree& x)             { return isTree(t, SIGINTCAST, x);          }
00186 
00187 bool  isSigFloatCast(Tree t)                    { Tree x; return isTree(t, SIGFLOATCAST, x);}
00188 bool  isSigFloatCast(Tree t, Tree& x)           { return isTree(t, SIGFLOATCAST, x);        }
00189 
00190 
00191 
00192 
00193 /*****************************************************************************
00194                              User Interface Elements
00195 *****************************************************************************/
00196 
00197 Sym SIGBUTTON = symbol ("SigButton");
00198 Tree sigButton   (Tree lbl)                 { return tree(SIGBUTTON, lbl);                  }
00199 bool isSigButton (Tree s)                   { Tree lbl; return isTree(s, SIGBUTTON, lbl);   }
00200 bool isSigButton (Tree s, Tree& lbl)        { return isTree(s, SIGBUTTON, lbl);             }
00201 
00202 
00203 Sym SIGCHECKBOX = symbol ("SigCheckbox");
00204 Tree sigCheckbox   (Tree lbl)               { return tree(SIGCHECKBOX, lbl);                    }
00205 bool isSigCheckbox (Tree s)                 { Tree lbl; return isTree(s, SIGCHECKBOX, lbl); }
00206 bool isSigCheckbox (Tree s, Tree& lbl)      { return isTree(s, SIGCHECKBOX, lbl);               }
00207 
00208 
00209 Sym SIGHSLIDER = symbol ("SigHSlider");
00210 Tree sigHSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
00211                                             { return tree(SIGHSLIDER, lbl, list4(cur,min,max,step));        }
00212 bool isSigHSlider (Tree s)                  { Tree lbl, params; return isTree(s, SIGHSLIDER, lbl, params);  }
00213 
00214 bool isSigHSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
00215 {
00216     Tree params;
00217     if (isTree(s, SIGHSLIDER, lbl, params)) {
00218         cur = nth(params, 0);
00219         min = nth(params, 1);
00220         max = nth(params, 2);
00221         step= nth(params, 3);
00222         return true;
00223     } else {
00224         return false;
00225     }
00226 }
00227 
00228 
00229 Sym SIGVSLIDER = symbol ("SigVSlider");
00230 Tree sigVSlider   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
00231                                             { return tree(SIGVSLIDER, lbl, list4(cur,min,max,step));        }
00232 bool isSigVSlider (Tree s)                  { Tree lbl, params; return isTree(s, SIGVSLIDER, lbl, params);  }
00233 
00234 bool isSigVSlider (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
00235 {
00236     Tree params;
00237     if (isTree(s, SIGVSLIDER, lbl, params)) {
00238         cur = nth(params, 0);
00239         min = nth(params, 1);
00240         max = nth(params, 2);
00241         step= nth(params, 3);
00242         return true;
00243     } else {
00244         return false;
00245     }
00246 }
00247 
00248 
00249 Sym SIGNUMENTRY = symbol ("SigNumEntry");
00250 Tree sigNumEntry   (Tree lbl, Tree cur, Tree min, Tree max, Tree step)
00251                                             { return tree(SIGNUMENTRY, lbl, list4(cur,min,max,step));       }
00252 bool isSigNumEntry (Tree s)                 { Tree lbl, params; return isTree(s, SIGNUMENTRY, lbl, params); }
00253 
00254 bool isSigNumEntry (Tree s, Tree& lbl, Tree& cur, Tree& min, Tree& max, Tree& step)
00255 {
00256     Tree params;
00257     if (isTree(s, SIGNUMENTRY, lbl, params)) {
00258         cur = nth(params, 0);
00259         min = nth(params, 1);
00260         max = nth(params, 2);
00261         step= nth(params, 3);
00262         return true;
00263     } else {
00264         return false;
00265     }
00266 }
00267 
00268 // output elements
00269 
00270 
00271 
00272 Sym SIGHBARGRAPH = symbol ("SigHBargraph");
00273 Tree sigHBargraph   (Tree lbl, Tree min, Tree max, Tree x)              { return tree(SIGHBARGRAPH, lbl, min, max, x);      }
00274 bool isSigHBargraph (Tree s)                                            { Tree lbl, min, max, x; return isTree(s, SIGHBARGRAPH, lbl, min, max, x);  }
00275 bool isSigHBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x)  { return isTree(s, SIGHBARGRAPH, lbl, min, max, x); }
00276 
00277 
00278 Sym SIGVBARGRAPH = symbol ("SigVBargraph");
00279 Tree sigVBargraph   (Tree lbl, Tree min, Tree max, Tree x)              { return tree(SIGVBARGRAPH, lbl, min, max, x);      }
00280 bool isSigVBargraph (Tree s)                                            { Tree lbl, min, max, x; return isTree(s, SIGVBARGRAPH, lbl, min, max, x);  }
00281 bool isSigVBargraph (Tree s, Tree& lbl, Tree& min, Tree& max, Tree& x)  { return isTree(s, SIGVBARGRAPH, lbl, min, max, x); }
00282 
00283 
00284 Sym SIGATTACH = symbol ("sigAttach");
00285 Tree  sigAttach(Tree t0, Tree t1)                   { return tree(SIGATTACH, t0, t1);       }
00286 bool  isSigAttach(Tree t, Tree& t0, Tree& t1)       { return isTree(t, SIGATTACH, t0, t1);  }
00287 
00288 
00289 
00290 Tree addNums(Tree a, Tree b)
00291 {
00292     Tree r = tree(addNode(a->node(),b->node()));
00293     //cerr.flags(ios::showpoint); cerr << "addNums " << *a << "+" << *b << " -> " << *r << endl;
00294     return r;
00295 }
00296 
00297 Tree subNums(Tree a, Tree b)
00298 {
00299     Tree r = tree(subNode(a->node(),b->node()));
00300     //cerr.flags(ios::showpoint); cerr << "subNums " << *a << "-" << *b << " -> " << *r << endl;
00301     return r;
00302 }
00303 
00304 Tree mulNums(Tree a, Tree b)
00305 {
00306     Tree r = tree(mulNode(a->node(),b->node()));
00307     //cerr.flags(ios::showpoint); cerr << "mulNums " << *a << "*" << *b << " -> " << *r << endl;
00308     return r;
00309 }
00310 
00311 Tree divNums(Tree a, Tree b)
00312 {
00313     Tree r = tree(divNode(a->node(),b->node()));
00314     //cerr.flags(ios::showpoint); cerr << "divNums " << *a << "/" << *b << " -> " << *r << endl;
00315     return r;
00316 }
00317 
00318 Tree divExtendedNums(Tree a, Tree b)
00319 {
00320     Tree r = tree(divExtendedNode(a->node(),b->node()));
00321     //cerr.flags(ios::showpoint); cerr << "divExtendeNums " << *a << "/" << *b << " -> " << *r << endl;
00322     return r;
00323 }
00324 
00325 Tree minusNum(Tree a)
00326 {
00327     Tree r = tree(minusNode(a->node()));
00328     //cerr.flags(ios::showpoint); cerr << "minusNum " << *a << " -> " << *r << endl;
00329     return r;
00330 }
00331 
00332 Tree inverseNum(Tree a)
00333 {
00334     Tree r = tree(inverseNode(a->node()));
00335     //cerr.flags(ios::showpoint); cerr << "inverseNum " << *a << " -> " << *r << endl;
00336     return r;
00337 }
00338 
00339 bool isSigAdd(Tree a, Tree& x, Tree& y)
00340 {
00341     int op;
00342     return isSigBinOp(a, &op, x, y) && (op == kAdd);
00343 }
00344 
00345 bool isSigMul(Tree a, Tree& x, Tree& y)
00346 {
00347     int op;
00348     return isSigBinOp(a, &op, x, y) && (op == kMul);
00349 }
00350 
00351 bool isSigSub(Tree a, Tree& x, Tree& y)
00352 {
00353     int op;
00354     return isSigBinOp(a, &op, x, y) && (op == kSub);
00355 }
00356 
00357 bool isSigDiv(Tree a, Tree& x, Tree& y)
00358 {
00359     int op;
00360     return isSigBinOp(a, &op, x, y) && (op == kDiv);
00361 }
00362 
00363 
00364 
00365 
00366 /*****************************************************************************
00367                              matrix extension
00368 *****************************************************************************/
00369 Sym SIGTUPLE        = symbol ("SigTuple");
00370 Sym SIGTUPLEACCESS  = symbol ("SigTupleAccess");
00371 
00372 // a tuple of signals is basically a list of signals.
00373 // mode = 0 means normal, mode = 1 means blocked
00374 Tree sigTuple (int mode, Tree ls)                   { return tree(SIGTUPLE, tree(mode), ls); }
00375 bool isSigTuple (Tree s, int* mode, Tree& ls)       { Tree m; return isTree(s, SIGTUPLE, m, ls) && isInt(m->node(), mode); }
00376 
00377 // Access the components of a tuple.
00378 // ts is tuple of signals, idx is a scalar signal between 0..n
00379 Tree sigTupleAccess(Tree ts, Tree idx)              { return tree(SIGTUPLEACCESS, ts, idx); }
00380 bool isSigTupleAccess(Tree s, Tree& ts, Tree& idx)  { return isTree(s, SIGTUPLEACCESS, ts, idx); }
00381 
00382 // create a tuple of signals
00383 Tree sigCartesianProd (Tree s1, Tree s2)
00384 {
00385     Tree    l1, l2;
00386     int     m1, m2;
00387 
00388     if (isSigTuple(s1, &m1, l1) && (m1 == 0)) {
00389         // nothing to do
00390     } else {
00391         l1 = list1(s1);
00392     }
00393 
00394     if (isSigTuple(s2, &m2, l2) && (m2 == 0)) {
00395         // nothing to do
00396     } else {
00397         l2 = list1(s2);
00398     }
00399 
00400 
00401     return sigTuple(0, concat(l1,l2));
00402 }
00403 
00404 
00405 
00412 bool verySimple(Tree exp)
00413 {
00414     int     i;
00415     double  r;
00416     Tree    type, name, file;
00417     
00418     return  isSigInt(exp, &i) 
00419             ||  isSigReal(exp, &r)
00420             ||  isSigInput(exp, &i)
00421             ||  isSigFConst(exp, type, name, file);
00422 }