|
FAUST compiler
0.9.9.6b8
|
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 #include "compile_sched.hh" 00025 #include "floats.hh" 00026 #include "ppsig.hh" 00027 00028 extern int gVecSize; 00029 00030 void SchedulerCompiler::compileMultiSignal (Tree L) 00031 { 00032 //contextor recursivness(0); 00033 L = prepare(L); // optimize, share and annotate expression 00034 00035 for (int i = 0; i < fClass->inputs(); i++) { 00036 fClass->addZone3(subst("$1* input$0 = &input[$0][fIndex];", T(i), xfloat())); 00037 } 00038 for (int i = 0; i < fClass->outputs(); i++) { 00039 fClass->addZone3(subst("$1* output$0 = &output[$0][fIndex];", T(i), xfloat())); 00040 } 00041 00042 fClass->addSharedDecl("fullcount"); 00043 fClass->addSharedDecl("input"); 00044 fClass->addSharedDecl("output"); 00045 00046 for (int i = 0; isList(L); L = tl(L), i++) { 00047 Tree sig = hd(L); 00048 fClass->openLoop("count"); 00049 fClass->addExecCode(subst("output$0[i] = $2$1;", T(i), CS(sig), xcast())); 00050 fClass->closeLoop(sig); 00051 } 00052 00053 // Build tasks list 00054 fClass->buildTasksList(); 00055 00056 generateUserInterfaceTree(prepareUserInterfaceTree(fUIRoot)); 00057 generateMacroInterfaceTree("", prepareUserInterfaceTree(fUIRoot)); 00058 if (fDescription) { 00059 fDescription->ui(prepareUserInterfaceTree(fUIRoot)); 00060 } 00061 } 00062 00063 00073 void SchedulerCompiler::vectorLoop (const string& tname, const string& vecname, const string& cexp) 00074 { 00075 // -- declare the vector 00076 fClass->addSharedDecl(vecname); 00077 00078 // -- variables moved as class fields... 00079 fClass->addDeclCode(subst("$0 \t$1[$2];", tname, vecname, T(gVecSize))); 00080 00081 // -- compute the new samples 00082 fClass->addExecCode(subst("$0[i] = $1;", vecname, cexp)); 00083 } 00084 00085 00095 void SchedulerCompiler::dlineLoop (const string& tname, const string& dlname, int delay, const string& cexp) 00096 { 00097 if (delay < gMaxCopyDelay) { 00098 00099 // Implementation of a copy based delayline 00100 00101 // create names for temporary and permanent storage 00102 string buf = subst("$0_tmp", dlname); 00103 string pmem= subst("$0_perm", dlname); 00104 00105 // constraints delay size to be multiple of 4 00106 delay = (delay+3)&-4; 00107 00108 // allocate permanent storage for delayed samples 00109 string dsize = T(delay); 00110 fClass->addDeclCode(subst("$0 \t$1[$2];", tname, pmem, dsize)); 00111 00112 // init permanent memory 00113 fClass->addInitCode(subst("for (int i=0; i<$1; i++) $0[i]=0;", pmem, dsize)); 00114 00115 // compute method 00116 00117 // -- declare a buffer and a "shifted" vector 00118 fClass->addSharedDecl(buf); 00119 00120 // -- variables moved as class fields... 00121 fClass->addDeclCode(subst("$0 \t$1[$2+$3];", tname, buf, T(gVecSize), dsize)); 00122 00123 fClass->addFirstPrivateDecl(dlname); 00124 fClass->addZone2(subst("$0* \t$1 = &$2[$3];", tname, dlname, buf, dsize)); 00125 00126 // -- copy the stored samples to the delay line 00127 fClass->addPreCode(subst("for (int i=0; i<$2; i++) $0[i]=$1[i];", buf, pmem, dsize)); 00128 00129 // -- compute the new samples 00130 fClass->addExecCode(subst("$0[i] = $1;", dlname, cexp)); 00131 00132 // -- copy back to stored samples 00133 fClass->addPostCode(subst("for (int i=0; i<$2; i++) $0[i]=$1[count+i];", pmem, buf, dsize)); 00134 00135 } else { 00136 00137 // Implementation of a ring-buffer delayline 00138 00139 // the size should be large enough and aligned on a power of two 00140 delay = pow2limit(delay + gVecSize); 00141 string dsize = T(delay); 00142 string mask = T(delay-1); 00143 00144 // create names for temporary and permanent storage 00145 string idx = subst("$0_idx", dlname); 00146 string idx_save = subst("$0_idx_save", dlname); 00147 00148 // allocate permanent storage for delayed samples 00149 fClass->addDeclCode(subst("$0 \t$1[$2];", tname, dlname, dsize)); 00150 fClass->addDeclCode(subst("int \t$0;", idx)); 00151 fClass->addDeclCode(subst("int \t$0;", idx_save)); 00152 00153 // init permanent memory 00154 fClass->addInitCode(subst("for (int i=0; i<$1; i++) $0[i]=0;", dlname, dsize)); 00155 fClass->addInitCode(subst("$0 = 0;", idx)); 00156 fClass->addInitCode(subst("$0 = 0;", idx_save)); 00157 00158 // -- update index 00159 fClass->addPreCode(subst("$0 = ($0+$1)&$2;", idx, idx_save, mask)); 00160 00161 // -- compute the new samples 00162 fClass->addExecCode(subst("$0[($2+i)&$3] = $1;", dlname, cexp, idx, mask)); 00163 00164 // -- save index 00165 fClass->addPostCode(subst("$0 = count;", idx_save)); 00166 } 00167 }
1.8.0