Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Parallel.cpp
Go to the documentation of this file.
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 }