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 "Parallel.h" 00020 00021 00022 using std::ostringstream; 00023 using std::vector; 00024 00025 using namespace Marsyas; 00026 00027 Parallel::Parallel(mrs_string name):MarSystem("Parallel",name) 00028 { 00029 isComposite_ = true; 00030 } 00031 00032 Parallel::~Parallel() 00033 { 00034 deleteSlices(); 00035 } 00036 00037 void Parallel::deleteSlices() 00038 { 00039 vector<realvec *>::const_iterator iter; 00040 for (iter = slices_.begin(); iter != slices_.end(); iter++) { 00041 delete *(iter); 00042 } 00043 slices_.clear(); 00044 } 00045 00046 MarSystem* Parallel::clone() const 00047 { 00048 return new Parallel(*this); 00049 } 00050 00051 void Parallel::myUpdate(MarControlPtr sender) 00052 { 00053 childInfos_.clear(); 00054 00055 child_count_t child_count = marsystems_.size(); 00056 if (child_count) 00057 { 00058 mrs_natural highestStabilizingDelay = ctrl_inStabilizingDelay_->to<mrs_natural>(); 00059 //propagate in flow controls to first child 00060 marsystems_[0]->setctrl("mrs_natural/inSamples", inSamples_); 00061 marsystems_[0]->setctrl("mrs_real/israte", israte_); 00062 marsystems_[0]->setctrl("mrs_natural/inStabilizingDelay", inStabilizingDelay_); 00063 00064 mrs_string inObsName; 00065 mrs_string temp; 00066 mrs_string inObsNames = ctrl_inObsNames_->to<mrs_string>(); 00067 00068 inObsName = inObsNames.substr(0, inObsNames.find(",")); 00069 temp = inObsNames.substr(inObsNames.find(",")+1, inObsNames.length()); 00070 inObsNames = temp; 00071 marsystems_[0]->setctrl("mrs_string/inObsNames", inObsName + ","); 00072 marsystems_[0]->update(); 00073 00074 mrs_natural inObservations = marsystems_[0]->getctrl("mrs_natural/inObservations")->to<mrs_natural>(); 00075 mrs_natural onObservations = marsystems_[0]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(); 00076 mrs_natural localStabilizingDelay = marsystems_[0]->getctrl("mrs_natural/onStabilizingDelay")->to<mrs_natural>(); 00077 if (highestStabilizingDelay < localStabilizingDelay) 00078 highestStabilizingDelay = localStabilizingDelay; 00079 00080 ostringstream oss; 00081 oss << marsystems_[0]->getctrl("mrs_string/onObsNames"); 00082 00083 for (child_count_t i=1; i < child_count; ++i) 00084 { 00085 marsystems_[i]->setctrl("mrs_natural/inSamples", marsystems_[0]->getctrl("mrs_natural/inSamples")); 00086 marsystems_[i]->setctrl("mrs_real/israte", marsystems_[0]->getctrl("mrs_real/israte")); //[!] israte 00087 marsystems_[i]->setctrl("mrs_natural/inStabilizingDelay", inStabilizingDelay_); 00088 00089 00090 inObsName = inObsNames.substr(0, inObsNames.find(",")); 00091 temp = inObsNames.substr(inObsNames.find(",")+1, inObsNames.length()); 00092 inObsNames = temp; 00093 marsystems_[i]->setctrl("mrs_string/inObsNames", inObsName + ","); 00094 00095 marsystems_[i]->update(); 00096 oss << marsystems_[i]->getctrl("mrs_string/onObsNames"); 00097 00098 inObservations += marsystems_[i]->getctrl("mrs_natural/inObservations")->to<mrs_natural>(); 00099 onObservations += marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(); 00100 localStabilizingDelay = marsystems_[0]->getctrl("mrs_natural/onStabilizingDelay")->to<mrs_natural>(); 00101 if (highestStabilizingDelay < localStabilizingDelay) 00102 highestStabilizingDelay = localStabilizingDelay; 00103 } 00104 00105 //forward flow propagation 00106 setctrl(ctrl_onSamples_, marsystems_[0]->getctrl("mrs_natural/onSamples")); 00107 setctrl(ctrl_onObservations_, onObservations); 00108 setctrl(ctrl_osrate_, marsystems_[0]->getctrl("mrs_real/osrate")); 00109 setctrl(ctrl_onObsNames_, oss.str()); 00110 setctrl(ctrl_onStabilizingDelay_, highestStabilizingDelay); 00111 00112 // update buffers for children MarSystems 00113 if(slices_.size() < 2*child_count) 00114 { 00115 slices_.resize(2*child_count, NULL); 00116 } 00117 00118 for (child_count_t i = 0; i < child_count; ++i) 00119 { 00120 if (slices_[2*i] != NULL) 00121 { 00122 if ((slices_[2*i])->getRows() != marsystems_[i]->getctrl("mrs_natural/inObservations")->to<mrs_natural>() || 00123 (slices_[2*i])->getCols() != marsystems_[i]->getctrl("mrs_natural/inSamples")->to<mrs_natural>()) 00124 { 00125 delete slices_[2*i]; 00126 slices_[2*i] = new realvec(marsystems_[i]->getctrl("mrs_natural/inObservations")->to<mrs_natural>(), 00127 marsystems_[i]->getctrl("mrs_natural/inSamples")->to<mrs_natural>()); 00128 } 00129 } 00130 else 00131 slices_[2*i] = new realvec(marsystems_[i]->getctrl("mrs_natural/inObservations")->to<mrs_natural>(), 00132 marsystems_[i]->getctrl("mrs_natural/inSamples")->to<mrs_natural>()); 00133 00134 (slices_[2*i])->setval(0.0); 00135 00136 if (slices_[2*i+1] != NULL) 00137 { 00138 if ((slices_[2*i+1])->getRows() != marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>() || 00139 (slices_[2*i+1])->getCols() != marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()) 00140 { 00141 delete slices_[2*i+1]; 00142 slices_[2*i+1] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), 00143 marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()); 00144 } 00145 } 00146 else 00147 slices_[2*i+1] = new realvec(marsystems_[i]->getctrl("mrs_natural/onObservations")->to<mrs_natural>(), 00148 marsystems_[i]->getctrl("mrs_natural/onSamples")->to<mrs_natural>()); 00149 00150 (slices_[2*i+1])->setval(0.0); 00151 00152 ChildInfo info; 00153 info.inObservations = marsystems_[i]->getControl("mrs_natural/inObservations")->to<mrs_natural>(); 00154 info.onObservations = marsystems_[i]->getControl("mrs_natural/onObservations")->to<mrs_natural>(); 00155 childInfos_.push_back(info); 00156 } 00157 } 00158 else //if composite is empty... 00159 MarSystem::myUpdate(sender); 00160 } 00161 00162 void Parallel::myProcess(realvec& in, realvec& out) 00163 { 00164 mrs_natural t,o; 00165 mrs_natural inIndex = 0; 00166 mrs_natural outIndex = 0; 00167 mrs_natural localIndex = 0; 00168 child_count_t child_count = marsystems_.size(); 00169 00170 if (child_count == 1) 00171 { 00172 marsystems_[0]->process(in, out); 00173 } 00174 else if (child_count > 1) 00175 { 00176 for (child_count_t i = 0; i < child_count; ++i) 00177 { 00178 localIndex = childInfos_[i].inObservations; 00179 for (o = 0; o < localIndex; o++) 00180 { 00181 // avoid reading unallocated memory 00182 if ((inIndex + o) < in.getRows()) { 00183 for (t = 0; t < inSamples_; t++) //lmartins: was t < onSamples [!] 00184 { 00185 (*(slices_[2*i]))(o,t) = in(inIndex + o,t); 00186 } 00187 } else { 00188 for (t = 0; t < inSamples_; t++) { 00189 (*(slices_[2*i]))(o,t) = 0; 00190 } 00191 } 00192 } 00193 inIndex += localIndex; 00194 marsystems_[i]->process(*(slices_[2*i]), *(slices_[2*i+1])); 00195 localIndex = childInfos_[i].onObservations; 00196 for (o = 0; o < localIndex; o++) 00197 { 00198 for (t = 0; t < onSamples_; t++) 00199 { 00200 out(outIndex + o,t) = (*(slices_[2*i+1]))(o,t); 00201 } 00202 } 00203 outIndex += localIndex; 00204 } 00205 } 00206 else if(child_count == 0) //composite has no children! 00207 { 00208 MRSWARN("Parallel::process: composite has no children MarSystems - passing input to output without changes."); 00209 out = in; 00210 } 00211 }