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 "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 }