Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/ResampleBezier.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 "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 }