Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Fanout.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 "Fanout.h"
00020 #include "../common_source.h"
00021 
00022 
00023 using std::ostringstream;
00024 using std::vector;
00025 using std::string;
00026 
00027 using namespace Marsyas;
00028 
00029 Fanout::Fanout(mrs_string name):MarSystem("Fanout", name)
00030 {
00031   isComposite_ = true;
00032   addControls();
00033 }
00034 
00035 Fanout::Fanout(const Fanout& a): MarSystem(a)
00036 {
00037   ctrl_enabled_ = getctrl("mrs_realvec/enabled");
00038   ctrl_muted_ = getctrl("mrs_realvec/muted");
00039 }
00040 
00041 Fanout::~Fanout()
00042 {
00043 }
00044 
00045 MarSystem*
00046 Fanout::clone() const
00047 {
00048   return new Fanout(*this);
00049 }
00050 
00051 void
00052 Fanout::addControls()
00053 {
00054   addctrl("mrs_natural/disable", -1);
00055   setctrlState("mrs_natural/disable", true);
00056   addctrl("mrs_natural/enable", -1);
00057   setctrlState("mrs_natural/enable", true);
00058 
00059   addctrl("mrs_string/enableChild", ",");
00060   setctrlState("mrs_string/enableChild", true);
00061   addctrl("mrs_string/disableChild", ",");
00062   setctrlState("mrs_string/disableChild", true);
00063 
00064   addctrl("mrs_realvec/enabled", realvec(), ctrl_enabled_);
00065   addctrl("mrs_realvec/muted", realvec(), ctrl_muted_);
00066 }
00067 
00068 void
00069 Fanout::myUpdate(MarControlPtr sender)
00070 {
00071   MarControlAccessor acc(ctrl_enabled_);
00072   mrs_realvec& enabled = acc.to<mrs_realvec>();
00073   mrs_natural child_count = (mrs_natural) marsystems_.size();
00074   if (enabled.getSize() < child_count)
00075   {
00076     enabled.create(child_count);
00077     enabled.setval(1.0); //all children enabled by default
00078   }
00079 
00080   MarControlAccessor accMuted(ctrl_muted_);
00081   mrs_realvec& muted = accMuted.to<mrs_realvec>();
00082   if (muted.getSize() < child_count)
00083   {
00084     muted.create(child_count);
00085     muted.setval(0.0); //all children unmuted by default
00086   }
00087 
00088   if (child_count)
00089   {
00090     children_info_.resize((size_t)child_count);
00091   }
00092 
00093   //check child MarSystems to disable (passed as a string)
00094   {
00095     const string & child_name_to_disable = getctrl("mrs_string/disableChild")->to<mrs_string>();
00096     if (child_name_to_disable == "all")
00097     {
00098       for (mrs_natural i=0; i < (mrs_natural) marsystems_.size(); ++i)
00099       {
00100         enabled(i) = 0.0;
00101         MRSDIAG("Fanout::myUpdate(): DISABLING child: " + marsystems_[i]->getAbsPath());
00102       }
00103     }
00104     else
00105     {
00106       for (mrs_natural i=0; i < (mrs_natural) marsystems_.size(); ++i)
00107       {
00108         mrs_string s;
00109         s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName();
00110         if (child_name_to_disable == s)
00111         {
00112           enabled(i) = 0.0;
00113           MRSDIAG("Fanout::myUpdate(): DISABLING child: " + marsystems_[i]->getAbsPath());
00114         }
00115       }
00116     }
00117     setctrl("mrs_string/disableChild", ",");
00118   }
00119   //check child MarSystem to disable (passed as an index)
00120   {
00121     mrs_natural child_index_to_disable = getctrl("mrs_natural/disable")->to<mrs_natural>();
00122     if (child_index_to_disable >= 0 && child_index_to_disable < child_count)
00123     {
00124       enabled(child_index_to_disable) = 0.0;
00125       MRSDIAG("Fanout::myUpdate(): DISABLING child: " + marsystems_[child_index_to_disable]->getAbsPath());
00126     }
00127     setctrl("mrs_natural/disable", -1);
00128   }
00129   //check child MarSystems to enable (passed as a string)
00130   {
00131     const string & child_name_to_enable = getctrl("mrs_string/enableChild")->to<mrs_string>();
00132     for (mrs_natural i=0; i < (mrs_natural) marsystems_.size(); ++i)
00133     {
00134       mrs_string s;
00135       s = marsystems_[i]->getType() + "/" + marsystems_[i]->getName();
00136       if (child_name_to_enable == s)
00137       {
00138         enabled(i) = 1.0;
00139         MRSDIAG("Fanout::myUpdate(): ENABLING child: " + marsystems_[i]->getAbsPath());
00140       }
00141     }
00142     setctrl("mrs_string/enableChild", ",");
00143   }
00144   //check child MarSystem to enable (passed as an index)
00145   {
00146     mrs_natural child_index_to_enable = getctrl("mrs_natural/enable")->to<mrs_natural>();
00147     if (child_index_to_enable > 0 && child_index_to_enable < child_count)
00148     {
00149       enabled(child_index_to_enable) = 1.0;
00150     }
00151     setctrl("mrs_natural/enable", -1);
00152   }
00153 
00154   for (mrs_natural i = 0; i < child_count; ++i)
00155   {
00156     children_info_[i].enabled = enabled(i) != 0.0;
00157   }
00158 
00159   if (!child_count)
00160   {
00161     MarSystem::myUpdate(sender);
00162     return;
00163   }
00164 
00165   // Configure children
00166 
00167   mrs_natural highestStabilizingDelay = ctrl_inStabilizingDelay_->to<mrs_natural>();
00168   ostringstream oss;
00169   mrs_natural out_observations = 0;
00170   mrs_natural out_samples = 0;
00171   mrs_real out_rate = 0.0;
00172 
00173   for (mrs_natural i=0; i < child_count; ++i)
00174   {
00175     MarSystem * child = marsystems_[i];
00176 
00177     child->setctrl("mrs_natural/inSamples", inSamples_);
00178     child->setctrl("mrs_natural/inObservations", inObservations_);
00179     child->setctrl("mrs_real/israte", israte_);
00180     child->setctrl("mrs_string/inObsNames", inObsNames_);
00181     child->setctrl("mrs_natural/inStabilizingDelay", inStabilizingDelay_);
00182     child->update(sender);
00183 
00184     mrs_natural child_out_observations = child->getctrl("mrs_natural/onObservations")->to<mrs_natural>();
00185     mrs_natural child_out_samples = child->getctrl("mrs_natural/onSamples")->to<mrs_natural>();
00186     mrs_real child_out_rate = child->getctrl("mrs_real/osrate")->to<mrs_real>();
00187 
00188     if (i == 0)
00189     {
00190       out_samples = child_out_samples;
00191       out_rate = child_out_rate;
00192     }
00193 
00194     if (children_info_[i].enabled)
00195     {
00196       bool output = (child_out_samples <= out_samples);
00197 
00198       children_info_[i].buffer.create( child_out_observations, child_out_samples );
00199       children_info_[i].output = output;
00200 
00201       if (output)
00202         out_observations += child_out_observations;
00203 
00204       mrs_natural localStabilizingDelay = child->getctrl("mrs_natural/onStabilizingDelay")->to<mrs_natural>();
00205       if (highestStabilizingDelay < localStabilizingDelay)
00206         highestStabilizingDelay = localStabilizingDelay;
00207 
00208       oss << child->getctrl("mrs_string/onObsNames");
00209     }
00210   }
00211 
00212   // Forward flow propagation
00213 
00214   setctrl(ctrl_onSamples_, out_samples);
00215   setctrl(ctrl_onObservations_, out_observations);
00216   setctrl(ctrl_osrate_, out_rate);
00217   setctrl(ctrl_onObsNames_, oss.str());
00218   setctrl(ctrl_onStabilizingDelay_, highestStabilizingDelay);
00219 }
00220 
00221 void
00222 Fanout::myProcess(realvec& in, realvec& out)
00223 {
00224   mrs_natural o,t;
00225   mrs_natural child_count = (mrs_natural) marsystems_.size();
00226   if (child_count)
00227   {
00228     mrs_natural out_observation_offset = 0;
00229 
00230     //MarControlAccessor acc(ctrl_enabled_);
00231     //mrs_realvec& enabled = acc.to<mrs_realvec>();
00232 
00233     MarControlAccessor accMuted(ctrl_muted_);
00234     mrs_realvec& muted = accMuted.to<mrs_realvec>();
00235 
00236     for (mrs_natural i = 0; i < child_count; ++i)
00237     {
00238       child_info & info = children_info_[i];
00239       mrs_natural child_observation_count = info.buffer.getRows();
00240       mrs_natural child_sample_count = info.buffer.getCols();
00241 
00242       if (info.enabled)
00243       {
00244         //check if the child is unmuted, otherwise just use the previous output
00245         if(!muted(i))
00246         {
00247           marsystems_[i]->process(in, info.buffer);
00248         }
00249 
00250         if (info.output)
00251         {
00252           for (o=0; o < child_observation_count; o++)
00253             for (t=0; t < child_sample_count; t++)
00254               out(out_observation_offset + o,t) = info.buffer(o,t);
00255 
00256           out_observation_offset += child_observation_count;
00257         }
00258       }
00259     }
00260   }
00261   else //composite has no children!
00262   {
00263     MRSWARN("FanOut::process: composite has no children MarSystems - passing input to output without changes.");
00264     out = in;
00265   }
00266 }