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 "ResampleBezier.h" 00020 00021 using namespace std; 00022 using namespace Marsyas; 00023 00033 ResampleBezier::ResampleBezier(mrs_string name):MarSystem("ResampleBezier", name) 00034 { 00035 //Add any specific controls needed by ResampleBezier 00036 //(default controls all MarSystems should have 00037 //were already added by MarSystem::addControl(), 00038 //called by :MarSystem(name) constructor). 00039 //If no specific controls are needed by a MarSystem 00040 //there is no need to implement and call this addControl() 00041 //method (see for e.g. Rms.cpp) 00042 addControls(); 00043 } 00044 00045 ResampleBezier::ResampleBezier(const ResampleBezier& a) : MarSystem(a) 00046 { 00047 // For any MarControlPtr in a MarSystem 00048 // it is necessary to perform this getctrl 00049 // in the copy constructor in order for cloning to work 00050 00051 00052 //mrs_bool ctrl_tangentMode - false: (default)tangent at interpolation point is derived from the previous and immediately following sample; 00053 // true: tangents at each interpolation point are parallel to the axis along the indices of the samples 00054 // which alows for smooth transition at frame endings, 00055 // maximum amplitude will be limited to the maximum prior to interpolation 00056 //mrs_bool ctrl_samplingRateAdjustmentMode - adjust new resulting SamplingRate for following Marsystems 00057 //mrs_real stretch - desired stretch ratio (number of output samples = input number of samples*stretch) 00058 //mrs_real offStart - (default:0) offset from the start (towards the end) of the Samples (if only a part of the samples should be used to interpolate) 00059 //mrs_real offEnd - (default:0) offset from the end (towards the start) of the Samples (if only a part of the samples should be used to interpolate) 00060 00061 00062 ctrl_offStart_ = getctrl("mrs_real/offStart"); 00063 ctrl_offEnd_ = getctrl("mrs_real/offEnd"); 00064 ctrl_tangentMode_ = getctrl("mrs_bool/tangentMode"); 00065 ctrl_samplingRateAdjustmentMode_ = getctrl("mrs_bool/samplingRateAdjustmentMode"); 00066 ctrl_stretch_ = getctrl("mrs_real/stretch"); 00067 00068 } 00069 00070 ResampleBezier::~ResampleBezier() 00071 { 00072 } 00073 00074 MarSystem* 00075 ResampleBezier::clone() const 00076 { 00077 return new ResampleBezier(*this); 00078 } 00079 00080 void 00081 ResampleBezier::addControls() 00082 { 00083 //Add specific controls needed by this MarSystem. 00084 addctrl("mrs_real/offStart", 0.0, ctrl_offStart_); 00085 addctrl("mrs_real/offEnd", 0.0, ctrl_offEnd_); 00086 addctrl("mrs_bool/samplingRateAdjustmentMode", (mrs_bool)true , ctrl_samplingRateAdjustmentMode_); 00087 addctrl("mrs_bool/tangentMode", (mrs_bool)false , ctrl_tangentMode_); 00088 addctrl("mrs_real/stretch", 1.0 , ctrl_stretch_); 00089 setctrlState("mrs_real/stretch", true); 00090 setctrlState("mrs_bool/samplingRateAdjustmentMode",(mrs_bool)true); 00091 00092 } 00093 00094 void 00095 ResampleBezier::myUpdate(MarControlPtr sender) 00096 { 00097 MarSystem::myUpdate(sender); 00098 00099 00100 mrs_real alpha = ctrl_stretch_->to<mrs_real>(); 00101 00102 ctrl_onSamples_->setValue((mrs_natural) (alpha * ctrl_inSamples_->to<mrs_natural>()), NOUPDATE); 00103 ctrl_onObservations_->setValue(ctrl_inObservations_->to<mrs_natural>()); 00104 if (!(ctrl_samplingRateAdjustmentMode_->to<mrs_bool>())) 00105 { 00106 alpha=1.0; 00107 } 00108 00109 ctrl_osrate_->setValue(ctrl_israte_->to<mrs_real>()*alpha); 00110 00111 00112 00113 mrs_string inObsNames = ctrl_inObsNames_->to<mrs_string>(); 00114 // Add prefix to the observation names. 00115 ctrl_onObsNames_->setValue(obsNamesAddPrefix(inObsNames, "ResampleBezier_"), NOUPDATE); 00116 00117 } 00118 00119 mrs_real 00120 ResampleBezier::interpolBezier(mrs_realvec px,mrs_real t) 00121 { 00122 mrs_natural n = px.getSize(); 00123 mrs_realvec q; 00124 q.create(n,n); 00125 00126 for (mrs_natural i=0; i<n; ++i) 00127 { 00128 q(i,0) = px(i); 00129 } 00130 00131 //j - number of interpolation step 00132 //i - number of points 00133 for (mrs_natural j=1; j<n; j++) 00134 { 00135 for (mrs_natural i=0; i<n-j; ++i) 00136 { 00137 q(i,j) = (1 - t) * q(i,j - 1) + t * q(i + 1,j - 1); 00138 } 00139 } 00140 return q(0,n-1); 00141 } 00142 00143 00144 void 00145 ResampleBezier::myProcess(realvec& in, realvec& out) 00146 { 00147 //cout << "-------------------------WORLD ENDING!!!" << endl; 00148 mrs_natural numb=inSamples_*3; //cubic bezier curve:2 control points for each interpolation point 00149 mrs_realvec sx; 00150 mrs_realvec sy; 00151 mrs_realvec bx; 00152 mrs_realvec by; 00153 sx.create(inSamples_); 00154 sy.create(inSamples_); 00155 bx.create(numb); 00156 by.create(numb); 00157 00158 mrs_realvec px; 00159 px.create(inSamples_); 00160 for(mrs_natural i=0; i<inSamples_; ++i) 00161 { 00162 px(i)=i; 00163 } 00164 00165 //#############chosen length parameterisation############ 00166 mrs_realvec u2; 00167 u2.create(inSamples_); 00168 00169 for (mrs_natural o=0; o<inObservations_; o++) 00170 { 00171 for (mrs_natural i=0; i<inSamples_; ++i) 00172 { 00173 00174 if (i!=inSamples_-1) 00175 { 00176 00177 if (i!=0) 00178 { 00179 u2(i)=u2(i-1)+sqrt((px(i)-px(i+1))*(px(i)-px(i+1))+(in(o,i)-in(o,i+1))*(in(o,i)-in(o,i+1))); 00180 } 00181 else 00182 { 00183 u2(0)=0; 00184 } 00185 } 00186 else 00187 { 00188 u2(i)=u2(i-1)+sqrt((px(i)-px(0))*(px(i)-px(0))+(in(o,i)-in(o,0))*(in(o,i)-in(o,0))); 00189 } 00190 } 00191 00193 00194 mrs_natural foo=(mrs_natural)0; 00195 mrs_natural bar=(mrs_natural)0; 00196 00197 mrs_real deltauk=(mrs_real)0.0; 00198 mrs_real deltaukm=(mrs_real)0.0; 00199 00200 mrs_bool tangentMode=ctrl_tangentMode_->to<mrs_bool>(); 00201 mrs_natural samplesout=getctrl("mrs_natural/onSamples")->to<mrs_natural>(); 00202 for(mrs_natural k=0; k<inSamples_; k++) 00203 { 00204 //indices for previous and next element with border management 00205 mrs_natural bla=k-1; 00206 if (bla<0) 00207 { 00208 bla=0; 00209 } 00210 mrs_natural blu=k+1; 00211 if (blu>inSamples_-1) 00212 { 00213 blu=inSamples_-1; 00214 } 00215 00216 //indices for previous and next bezier points with border management 00217 //this are the indizes of the control points that do not actually lie on the interpolation polynomial 00218 //unlike each point with an index of 3*k 00219 foo=(3*k-1)%numb; 00220 if (foo<0) 00221 { 00222 foo=foo+numb; 00223 } 00224 bar=(3*k+1)%numb; 00225 if (bar<0) 00226 { 00227 bar=bar+numb; 00228 } 00229 00230 if (k>=2) 00231 { 00232 deltauk=u2(k)-u2(k-1); 00233 deltaukm=u2(k-1)-u2(k-2); 00234 } 00235 else 00236 { 00237 deltauk=0.5; 00238 deltaukm=0.5; 00239 } 00240 if (tangentMode==(mrs_bool)true) 00241 { 00242 00243 sx(k)=(px(blu)-px(bla))/(deltauk+deltaukm); //normalization for non equidistant parameterization 00244 sy(k)=(in(o,blu)-in(o,bla))/(deltauk+deltaukm); //normalization for non equidistant parameterization 00245 00246 bx(foo)=px(k)-deltaukm*sx(k)/2.0; 00247 by(foo)=in(o,k)-deltaukm*sy(k)/2.0; 00248 00249 bx(3*k)=px(k); 00250 by(3*k)=in(o,k); 00251 00252 bx(bar)=px(k)+deltauk*sx(k)/2.0; 00253 by(bar)=in(o,k)+deltauk*sy(k)/2.0; 00254 } 00255 else 00256 { 00257 sx(k)=(px(blu)-px(bla))/(deltauk+deltaukm); 00258 00259 sy(k)=(in(o,blu)-in(o,bla))/(deltauk+deltaukm); 00260 00261 bx(foo)=px(k)-0.5*(px(k)-px(bla)); 00262 00263 by(foo)=in(o,k); 00264 00265 bx(3*k)=px(k); 00266 by(3*k)=in(o,k); 00267 00268 bx(bar)=px(k)+0.5*(px(blu)-px(k)); 00269 by(bar)=in(o,k); 00270 } 00271 } 00272 //endof for 00273 mrs_real offStart=ctrl_offStart_->to<mrs_real>(); 00274 mrs_real offEnd=ctrl_offEnd_->to<mrs_real>(); 00275 00276 mrs_real ratio=(inSamples_-1-offStart-offEnd)/(mrs_real)(samplesout-1); 00277 mrs_natural index=0; 00278 mrs_realvec ix; 00279 mrs_realvec yp; 00280 ix.create(4); 00281 yp.create(4); 00282 for(mrs_natural i=0; i<samplesout; ++i) 00283 { 00284 mrs_real ra=offStart+i*ratio; 00285 while (index+1<ra) 00286 { 00287 index=index+1; 00288 } 00289 for(mrs_natural j=0; j<4; j++) 00290 { 00291 ix(j)=bx((3*index+j)%((int)inSamples_*3)); 00292 yp(j)=by((3*index+j)%((int)inSamples_*3)); 00293 } 00294 00295 mrs_real difference=ra-index; 00296 out(o,i)=interpolBezier(yp, difference); 00297 } 00298 } 00299 00300 }