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