Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca> 00003 ** 00004 ** This program is free software; you can redistribute it and/or modify 00005 ** it under the terms of the GNU General Public License as published by 00006 ** the Free Software Foundation; either version 2 of the License, or 00007 ** (at your option) any later version. 00008 ** 00009 ** This program is distributed in the hope that it will be useful, 00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 ** GNU General Public License for more details. 00013 ** 00014 ** You should have received a copy of the GNU General Public License 00015 ** along with this program; if not, write to the Free Software 00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include "FanOutIn.h" 00020 #include <algorithm> 00021 00022 using std::ostringstream; 00023 using std::vector; 00024 using std::max; 00025 using std::min; 00026 00027 using namespace Marsyas; 00028 00029 FanOutIn::FanOutIn(mrs_string name):MarSystem("FanOutIn", name) 00030 { 00031 isComposite_ = true; 00032 wrongOutConfig_ = false; 00033 addControls(); 00034 } 00035 00036 FanOutIn::FanOutIn(const FanOutIn& a):MarSystem(a) 00037 { 00038 ctrl_combinator_ = getctrl("mrs_string/combinator"); 00039 wrongOutConfig_ = false; 00040 } 00041 00042 FanOutIn::~FanOutIn() 00043 { 00044 deleteSlices(); 00045 } 00046 00047 void 00048 FanOutIn::deleteSlices() 00049 { 00050 vector<realvec *>::const_iterator iter; 00051 for (iter= slices_.begin(); iter != slices_.end(); iter++) 00052 { 00053 delete *(iter); 00054 } 00055 slices_.clear(); 00056 } 00057 00058 MarSystem* 00059 FanOutIn::clone() const 00060 { 00061 return new FanOutIn(*this); 00062 } 00063 00064 void 00065 FanOutIn::addControls() 00066 { 00067 addctrl("mrs_natural/disable", -1); 00068 setctrlState("mrs_natural/disable", true); 00069 addctrl("mrs_natural/enable", -1); 00070 setctrlState("mrs_natural/enable", true); 00071 00072 addctrl("mrs_string/enableChild", ""); 00073 setctrlState("mrs_string/enableChild", true); 00074 addctrl("mrs_string/disableChild", ""); 00075 setctrlState("mrs_string/disableChild", true); 00076 00077 addctrl("mrs_string/combinator", "+", ctrl_combinator_); 00078 } 00079 00080 void 00081 FanOutIn::myUpdate(MarControlPtr sender) 00082 { 00083 child_count_t child_count = marsystems_.size(); 00084 if (enabled_.getSize() != child_count) 00085 { 00086 enabled_.create(child_count); 00087 enabled_.setval(1.0); 00088 } 00089 00090 //check child MarSystems to disable (passed as a string) 00091 disableChild_ = getctrl("mrs_string/disableChild")->to<mrs_string>(); 00092 disableChildIndex_ = -1; 00093 for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i) 00094 { 00095 mrs_string s; 00096 s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName(); 00097 if (disableChild_ == s) 00098 disableChildIndex_ = i; 00099 } 00100 if (disableChildIndex_ != -1) 00101 { 00102 enabled_(disableChildIndex_) = 0.0; 00103 setctrl("mrs_string/disableChild", ""); 00104 } 00105 if (disableChild_ == "all") 00106 { 00107 for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i) 00108 { 00109 enabled_(i) = 0.0; 00110 setctrl("mrs_string/disableChild", ""); 00111 } 00112 } 00113 00114 //check child MarSystem to disable (passed as an index) 00115 disable_ = getctrl("mrs_natural/disable")->to<mrs_natural>(); 00116 if (disable_ != -1 && disable_ < (mrs_natural) child_count) 00117 { 00118 enabled_(disable_) = 0.0; 00119 setctrl("mrs_natural/disable", -1); 00120 } 00121 else 00122 setctrl("mrs_natural/disable", -1); 00123 00124 //check child MarSystems to enable (passed as a string) 00125 enableChild_ = getctrl("mrs_string/enableChild")->to<mrs_string>(); 00126 enableChildIndex_ = -1; 00127 for (mrs_natural i=0; i < (mrs_natural)marsystems_.size(); ++i) 00128 { 00129 mrs_string s; 00130 s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName(); 00131 if (enableChild_ == s) 00132 enableChildIndex_ = i; 00133 } 00134 if (enableChildIndex_ != -1) 00135 { 00136 enabled_(enableChildIndex_) = 1.0; 00137 setctrl("mrs_string/enableChild", ""); 00138 } 00139 //check child MarSystem to enable (passed as an index) 00140 enable_ = getctrl("mrs_natural/enable")->to<mrs_natural>(); 00141 if (enable_ != -1 && enable_ < (mrs_natural) child_count) 00142 { 00143 enabled_(enable_) = 1.0; 00144 setctrl("mrs_natural/enable", -1); 00145 } 00146 else 00147 setctrl("mrs_natural/enable", -1); 00148 00149 if (child_count) 00150 { 00151 wrongOutConfig_ = false; 00152 00153 //propagate in flow controls to first child 00154 marsystems_[0]->setctrl("mrs_natural/inObservations", inObservations_); 00155 marsystems_[0]->setctrl("mrs_natural/inSamples", inSamples_); 00156 marsystems_[0]->setctrl("mrs_real/israte", israte_); 00157 marsystems_[0]->setctrl("mrs_string/inObsNames", inObsNames_); 00158 marsystems_[0]->update(); 00159 00160 // update dataflow component MarSystems in order 00161 for (child_count_t i=1; i < child_count; ++i) 00162 { 00163 marsystems_[i]->setctrl("mrs_natural/inSamples", marsystems_[0]->getctrl("mrs_natural/inSamples")); 00164 marsystems_[i]->setctrl("mrs_natural/inObservations", marsystems_[0]->getctrl("mrs_natural/inObservations")); 00165 marsystems_[i]->setctrl("mrs_real/israte", marsystems_[0]->getctrl("mrs_real/israte")); 00166 marsystems_[i]->setctrl("mrs_string/inObsNames", marsystems_[0]->getctrl("mrs_string/inObsNames")); 00167 marsystems_[i]->update(sender); 00168 00169 if(marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>() != 00170 marsystems_[0]->getctrl("mrs_natural/onSamples")->to<mrs_natural>() || 00171 marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>() != 00172 marsystems_[0]->getctrl("mrs_natural/onObservations")->to<mrs_natural>()) 00173 { 00174 //MRSERR("FanInOut::myUpdate - child MarSystem " + marsystems_[i]->getPrefix() + 00175 // " ouput configuration is not the same as the one from the first child MarSystem(" + 00176 // marsystems_[0]->getPrefix() + " ! Outputing zero valued result..."); 00177 wrongOutConfig_ = true; 00178 } 00179 } 00180 00181 // forward flow propagation 00182 setctrl(ctrl_onSamples_, marsystems_[0]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()); 00183 setctrl(ctrl_onObservations_, marsystems_[0]->getctrl("mrs_natural/onObservations")->to<mrs_natural>()); 00184 setctrl(ctrl_osrate_, marsystems_[0]->getctrl("mrs_real/osrate")->to<mrs_real>()); 00185 ostringstream oss; 00186 oss << marsystems_[0]->getctrl("mrs_string/onObsNames"); 00187 setctrl(ctrl_onObsNames_, oss.str()); 00188 00189 // update buffers between components 00190 if (slices_.size() < child_count) 00191 slices_.resize(child_count, NULL); 00192 for (child_count_t i=0; i< child_count; ++i) 00193 { 00194 if (slices_[i] != NULL) 00195 { 00196 if ((slices_[i])->getRows() != marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>() || 00197 (slices_[i])->getCols() != marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) 00198 { 00199 delete slices_[i]; 00200 slices_[i] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), 00201 marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()); 00202 } 00203 } 00204 else 00205 { 00206 slices_[i] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), 00207 marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()); 00208 } 00209 (slices_[i])->setval(0.0); 00210 } 00211 } 00212 else //if composite is empty... 00213 MarSystem::myUpdate(sender); 00214 } 00215 00216 void 00217 FanOutIn::myProcess(realvec& in, realvec& out) 00218 { 00219 child_count_t child_count = marsystems_.size(); 00220 if(child_count) 00221 { 00222 if(ctrl_combinator_->to<mrs_string>() == "+") 00223 out.setval(0); //identity operator 00224 if(ctrl_combinator_->to<mrs_string>() == "*") 00225 out.setval(1); //identity operator 00226 if(ctrl_combinator_->to<mrs_string>() == "max") 00227 out.setval(-1.0*MAXREAL); 00228 if(ctrl_combinator_->to<mrs_string>() == "min") 00229 out.setval(MAXREAL); 00230 00231 if(wrongOutConfig_) 00232 { 00233 //if there is a child with a non matching output configuration, just output zeros 00234 MRSERR("FanInOut::myUpdate - at least one child MarSystem ouput \ 00235 configuration is not the same as the one from the first child \ 00236 MarSystem! Outputing zero valued result..."); 00237 out.setval(0); 00238 return; 00239 } 00240 00241 for (child_count_t i = 0; i < child_count; ++i) 00242 { 00243 if (enabled_(i)) 00244 { 00245 marsystems_[i]->process(in, *(slices_[i])); 00246 if(ctrl_combinator_->to<mrs_string>() == "+") 00247 { 00248 out += *(slices_[i]); 00249 } 00250 if(ctrl_combinator_->to<mrs_string>() == "*") 00251 { 00252 out *= *(slices_[i]); 00253 } 00254 if(ctrl_combinator_->to<mrs_string>() == "max") 00255 { 00256 for(mrs_natural l=0; l<out.getRows(); ++l) 00257 for(mrs_natural c=0; c<out.getCols(); ++c) 00258 out(l,c) = max(out(l,c), (*(slices_[i]))(l,c)); 00259 } 00260 if(ctrl_combinator_->to<mrs_string>() == "min") 00261 { 00262 for(mrs_natural l=0; l<out.getRows(); ++l) 00263 for(mrs_natural c=0; c<out.getCols(); ++c) 00264 out(l,c) = min(out(l,c), (*(slices_[i]))(l,c)); 00265 } 00266 } 00267 } 00268 } 00269 else //composite has no children! 00270 { 00271 MRSWARN("FanOutIn::process: composite has no children MarSystems - passing input to output without changes."); 00272 out = in; 00273 } 00274 }