00001 /* 00002 ** Copyright (C) 1998-2006 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 "MarSystemTemplateMedium.h" 00020 00021 using std::ostringstream; 00022 using namespace Marsyas; 00023 00024 MarSystemTemplateMedium::MarSystemTemplateMedium(mrs_string name):MarSystem("MarSystemTemplateMedium", name) 00025 { 00026 // Add any specific controls needed by this MarSystem 00027 // (default controls all MarSystems should have 00028 // were already added by MarSystem::addControl(), 00029 // called by :MarSystem(name) constructor). 00030 // If no specific controls are needed by a MarSystem 00031 // there is no need to implement and call this addControl() 00032 // method (see for e.g. Rms.cpp) 00033 addControls(); 00034 } 00035 00036 MarSystemTemplateMedium::MarSystemTemplateMedium(const MarSystemTemplateMedium& a) : MarSystem(a) 00037 { 00038 // IMPORTANT! 00039 // All member "pointers" to controls have to be 00040 // explicitly reassigned here, at the copy ctor. 00041 // Otherwise these member "pointers" would be invalid! 00042 ctrl_repeats_EXAMPLE_ = getctrl("mrs_natural/repeats"); 00043 ctrl_gain_EXAMPLE_ = getctrl("mrs_real/gain"); 00044 } 00045 00046 00047 MarSystemTemplateMedium::~MarSystemTemplateMedium() 00048 { 00049 } 00050 00051 MarSystem* 00052 MarSystemTemplateMedium::clone() const 00053 { 00054 return new MarSystemTemplateMedium(*this); 00055 } 00056 00057 void 00058 MarSystemTemplateMedium::addControls() 00059 { 00060 // Add any specific controls needed by this MarSystem. 00061 00062 // Let's start by adding a dummy control (to which we will not use 00063 // a "pointer", just to illustrate the "traditional", yet 00064 // not so efficient way of using controls) 00065 addctrl("mrs_bool/dummy", false); 00066 // in this case this control should have state, since 00067 // other controls will depend on it. 00068 // (i.e. any change to it will call MarSystem::update() 00069 // which then calls myUpdate(MarControlPtr sender)) 00070 setctrlState("mrs_bool/dummy", true); 00071 00072 // if a "pointer" to a control is to be used (for efficiency purposes 00073 // - see myProcess() bellow), it should be passed as the last 00074 // argument to addctrl() 00075 addctrl("mrs_real/gain", 1.0, ctrl_gain_EXAMPLE_); 00076 // IMPORTANT NOTE: 00077 // in the above case, since the control value is supposed to 00078 // be a mrs_real, the default value also has to be a mrs_real! 00079 // if not (e.g. initialiting with "1" instead of "1.0"), the 00080 // control will in fact have a mrs_natural value despite of 00081 // the "mrs_real/..." name. 00082 00083 addctrl("mrs_natural/repeats", 1, ctrl_repeats_EXAMPLE_); 00084 // if we have a "pointer" to a control, we can set its state 00085 // in a different and more efficient way 00086 ctrl_repeats_EXAMPLE_->setState(true); 00087 } 00088 00089 void 00090 MarSystemTemplateMedium::myUpdate(MarControlPtr sender) 00091 { 00092 MRSDIAG("MarSystemTemplateMedium.cpp - MarSystemTemplateMedium:myUpdate"); 00093 00094 00095 MarSystem::myUpdate(sender); 00096 // As an example, this MarSystem will output a nr of repeated input frames 00097 // 00098 // The traditional (and still valid), but inefficient way to set controls: 00099 // 00100 //setctrl("mrs_natural/onObservations", getctrl("mrs_natural/inObservations")); 00101 //setctrl("mrs_real/osrate", getctrl("mrs_real/israte")); 00102 //setctrl("mrs_string/onObsNames", getctrl("mrs_string/inObsNames")); 00103 //... 00104 // 00105 // more efficient way to set the value of a control 00106 // (if we have a "pointer" to it - see addControls(), above). 00107 // setValue() always calls update() if the control in cause has state. 00108 // To avoid calling update() (and avoid recursion since we are already 00109 // inside update()/myUpdate(MarControlPtr sender)), setValue() should be called with the 00110 // NOUPDATE flag, as bellow: 00111 /* 00112 ctrl_onObservations_->setValue(ctrl_inObservations_, NOUPDATE); 00113 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00114 ctrl_onObsNames_->setValue(ctrl_inObsNames_, NOUPDATE); 00115 */ 00116 // here it's possible to see how the "repeats" control 00117 // affects the onSamples control (i.e. output number of samples) 00118 // 00119 // IMPORTANT: Since this changes the onSamples control, if this 00120 // MarSystem is inside a Composite, the Composite::update() must be 00121 // called afterwards in the main code, otherwise the size of the 00122 // corresponding slice will not be updated accordingly! 00123 // (see marsyasTests.cpp >> test_MarControls() ) 00124 // 00125 ctrl_onSamples_->setValue(ctrl_inSamples_ * ctrl_repeats_EXAMPLE_, NOUPDATE); 00126 00127 // NOTE: 00128 // see Gain.cpp for some more info about output parameter configuration. 00129 } 00130 00131 void 00132 MarSystemTemplateMedium::myProcess(realvec& in, realvec& out) 00133 { 00134 mrs_natural t,o; 00135 // FIXME Variable (rep) appears to be unused. 00136 // static mrs_natural rep = 1; 00137 static realvec vec; 00138 00139 const mrs_real& gainValue = ctrl_gain_EXAMPLE_->to<mrs_real>(); 00140 // this is equivalent (although slightly more efficient) to: 00141 // 00142 // mrs_real& gainValue = ctrl_gain_EXAMPLE_->to<mrs_real>(); // ::toReal() calls ::to<mrs_real>() 00143 // 00144 // This reference will not allow writing directly to the control, but 00145 // avoids a copy (which can hurt if the control is a big realvec) 00146 // and even if by some means the control value is modified elsewhere (e.g. by a 00147 // different thread), it's always in sync with the actual control value. 00148 00149 // There may be cases where is more adequate to get a copy of the control value, 00150 // so it does not change event if the actual control value is changed elsewhere: 00151 mrs_natural repeats = ctrl_repeats_EXAMPLE_->to<mrs_natural>(); 00152 00153 for (o=0; o < inObservations_; o++) 00154 for (t = 0; t < inSamples_; t++) 00155 for(mrs_natural r= 0; r < repeats; ++r) 00156 out(o,t+r*inSamples_) = gainValue * in(o,t); 00157 00158 // Just as an example, let's assume we want to write to a control 00159 // (e.g. some weird amplitude modulation effect), this is the way 00160 // to do it: 00161 mrs_real g = (((mrs_natural)(gainValue*10)+1)%10)/10.0; 00162 ctrl_gain_EXAMPLE_->setValue(g); 00163 }
1.5.6