|
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 #include "recSchema.h" 00024 #include <iostream> 00025 #include <assert.h> 00026 00027 using namespace std; 00028 00034 schema* makeRecSchema (schema* s1, schema* s2) 00035 { 00036 schema* a = makeEnlargedSchema(s1, s2->width()); 00037 schema* b = makeEnlargedSchema(s2, s1->width()); 00038 double m = dWire * max(b->inputs(), b->outputs()); 00039 double w = a->width() + 2*m; 00040 00041 return new recSchema(a,b,w); 00042 } 00043 00048 recSchema::recSchema (schema* s1, schema* s2, double width) 00049 : schema( s1->inputs() - s2->outputs(), 00050 s1->outputs(), 00051 width, 00052 s1->height() + s2->height() ), 00053 fSchema1(s1), 00054 fSchema2(s2) 00055 { 00056 // this version only accepts legal expressions of same width 00057 assert(s1->inputs() >= s2->outputs()); 00058 assert(s1->outputs() >= s2->inputs()); 00059 assert(s1->width() >= s2->width()); 00060 00061 // create the input and output points 00062 for (unsigned int i=0; i<inputs(); i++) fInputPoint.push_back(point(0,0)); 00063 for (unsigned int i=0; i<outputs(); i++) fOutputPoint.push_back(point(0,0)); 00064 00065 } 00066 00071 void recSchema::place(double ox, double oy, int orientation) 00072 { 00073 beginPlace(ox, oy, orientation); 00074 00075 double dx1 = (width() - fSchema1->width())/2; 00076 double dx2 = (width() - fSchema2->width())/2; 00077 00078 // place the two sub diagrams 00079 if (orientation == kLeftRight) { 00080 fSchema2->place(ox+dx2, oy, kRightLeft); 00081 fSchema1->place(ox+dx1, oy+fSchema2->height(), kLeftRight); 00082 } else { 00083 fSchema1->place(ox+dx1, oy, kRightLeft); 00084 fSchema2->place(ox+dx2, oy+fSchema1->height(), kLeftRight); 00085 } 00086 00087 00088 // adjust delta space to orientation 00089 if (orientation == kRightLeft) { dx1 = -dx1; } 00090 00091 // place input points 00092 for (unsigned int i=0; i<inputs(); i++) { 00093 point p = fSchema1->inputPoint(i+fSchema2->outputs()); 00094 fInputPoint[i] = point(p.x-dx1, p.y); 00095 } 00096 00097 // place output points 00098 for (unsigned int i=0; i<outputs(); i++) { 00099 point p = fSchema1->outputPoint(i); 00100 fOutputPoint[i] = point(p.x+dx1, p.y); 00101 } 00102 00103 endPlace(); 00104 } 00105 00106 00110 point recSchema::inputPoint(unsigned int i) const 00111 { 00112 return fInputPoint[i]; 00113 } 00114 00115 00119 point recSchema::outputPoint(unsigned int i) const 00120 { 00121 return fOutputPoint[i]; 00122 } 00123 00124 00130 void recSchema::draw(device& dev) 00131 { 00132 assert(placed()); 00133 00134 // draw the two subdiagrams 00135 fSchema1->draw(dev); 00136 fSchema2->draw(dev); 00137 00138 // draw the output lines 00139 for (unsigned int i=0; i<outputs(); i++) { 00140 point p = fSchema1->outputPoint(i); 00141 point q = outputPoint(i); 00142 //dev.trait(p.x, p.y, q.x, q.y); 00143 } 00144 00145 // draw the input lines 00146 unsigned int skip = fSchema2->outputs(); 00147 for (unsigned int i=0; i<inputs(); i++) { 00148 point p = fSchema1->inputPoint(i+skip); 00149 point q = inputPoint(i); 00150 //dev.trait(p.x, p.y, q.x, q.y); 00151 } 00152 00153 // draw the feedback connections to each fSchema2 input 00154 for (unsigned int i=0; i<fSchema2->inputs(); i++) { 00155 drawFeedback(dev, fSchema1->outputPoint(i), fSchema2->inputPoint(i), i*dWire); 00156 } 00157 00158 // draw the feedfront connections from each fSchema2 output 00159 for (unsigned int i=0; i<fSchema2->outputs(); i++) { 00160 drawFeedfront(dev, fSchema2->outputPoint(i), fSchema1->inputPoint(i), i*dWire); 00161 } 00162 } 00163 00164 00168 void recSchema::drawDelaySign(device& dev, double x, double y, double size) 00169 { 00170 dev.trait(x-size/2, y, x-size/2, y-size); 00171 dev.trait(x-size/2, y-size, x+size/2, y-size); 00172 dev.trait(x+size/2, y-size, x+size/2, y); 00173 } 00174 00175 00181 void recSchema::collectTraits(collector& c) 00182 { 00183 assert(placed()); 00184 00185 // draw the two subdiagrams 00186 fSchema1->collectTraits(c); 00187 fSchema2->collectTraits(c); 00188 00189 // draw the feedback connections to each fSchema2 input 00190 for (unsigned int i=0; i<fSchema2->inputs(); i++) { 00191 collectFeedback(c, fSchema1->outputPoint(i), fSchema2->inputPoint(i), i*dWire, outputPoint(i)); 00192 } 00193 00194 // draw the non recursive output lines 00195 for (unsigned int i=fSchema2->inputs(); i<outputs(); i++) { 00196 point p = fSchema1->outputPoint(i); 00197 point q = outputPoint(i); 00198 c.addTrait(trait(p,q)); // in->out order 00199 } 00200 00201 // draw the input lines 00202 unsigned int skip = fSchema2->outputs(); 00203 for (unsigned int i=0; i<inputs(); i++) { 00204 point p = inputPoint(i); 00205 point q = fSchema1->inputPoint(i+skip); 00206 c.addTrait(trait(p,q)); // in->out order 00207 } 00208 00209 // draw the feedfront connections from each fSchema2 output 00210 for (unsigned int i=0; i<fSchema2->outputs(); i++) { 00211 collectFeedfront(c, fSchema2->outputPoint(i), fSchema1->inputPoint(i), i*dWire); 00212 } 00213 } 00214 00215 00216 00221 void recSchema::drawFeedback(device& dev, const point& src, const point& dst, double dx) 00222 { 00223 double ox = src.x + ((orientation()==kLeftRight) ? dx : -dx); 00224 double ct = (orientation()==kLeftRight) ? dWire/2 : -dWire/2; 00225 00226 drawDelaySign(dev, ox, src.y, ct); 00227 //dev.trait(ox, src.y-ct, ox, dst.y); 00228 //dev.trait(ox, dst.y, dst.x, dst.y); 00229 } 00230 00231 00232 00237 void recSchema::collectFeedback(collector& c, const point& src, const point& dst, double dx, const point& out) 00238 { 00239 double ox = src.x + ((orientation()==kLeftRight) ? dx : -dx); 00240 double ct = (orientation()==kLeftRight) ? dWire/2 : -dWire/2; 00241 00242 point up(ox, src.y-ct); 00243 point br(ox+ct/2.0, src.y); 00244 00245 c.addOutput(up); 00246 c.addOutput(br); 00247 c.addInput(br); 00248 00249 c.addTrait(trait(up, point(ox, dst.y))); 00250 c.addTrait(trait(point(ox, dst.y), point(dst.x, dst.y))); 00251 c.addTrait(trait(src,br)); 00252 c.addTrait(trait(br,out)); 00253 00254 } 00255 00256 00261 void recSchema::drawFeedfront(device& dev, const point& src, const point& dst, double dx) 00262 { 00263 // double ox = src.x + ((orientation()==kLeftRight) ? -dx : dx); 00264 00265 // dev.trait(ox, src.y, src.x, src.y); 00266 // dev.trait(ox, src.y, ox, dst.y); 00267 // dev.trait(ox, dst.y, dst.x, dst.y); 00268 } 00269 00270 00275 void recSchema::collectFeedfront(collector& c, const point& src, const point& dst, double dx) 00276 { 00277 double ox = src.x + ((orientation()==kLeftRight) ? -dx : dx); 00278 00279 c.addTrait(trait(point(src.x, src.y), point(ox, src.y))); 00280 c.addTrait(trait(point(ox, src.y), point(ox, dst.y))); 00281 c.addTrait(trait(point(ox, dst.y), point(dst.x, dst.y))); 00282 }
1.8.0