SegmentSMSTimeStretch.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #include "SegmentSMSTimeStretch.hxx"
00023 #include "ProcessingFactory.hxx"
00024 
00025 
00026 
00027 namespace CLAM
00028 {
00029 
00030 namespace Hidden
00031 {       
00032         static const char * metadata[] = {
00033                 "key", "SegmentSMSTimeStretch",
00034 //              "category", "SMS Transformations",
00035                 "description", "SegmentSMSTimeStretch",
00036                 0
00037         };
00038         static FactoryRegistrator<ProcessingFactory, SegmentSMSTimeStretch> reg = metadata;
00039 }
00040 
00041 SegmentSMSTimeStretch::SegmentSMSTimeStretch():mAmount("Amount",this)
00042 {
00043         mSynthesisTime=0;
00044         mAnalysisTime=0;
00045         mCurrentInputFrame=-1;
00046         Configure(SegmentSMSTimeStretchConfig());
00047 }
00048 
00049 SegmentSMSTimeStretch::SegmentSMSTimeStretch(const SegmentTransformationConfig &c):SegmentTransformation(c),mAmount("Amount",this)
00050 {
00051         mSynthesisTime=0;
00052         mAnalysisTime=0;
00053         mCurrentInputFrame=-1;
00054         Configure(c);
00055 }
00056 
00057 bool SegmentSMSTimeStretch::ConcreteConfigure(const ProcessingConfig& cfg)
00058 {
00059         CopyAsConcreteConfig(mConcreteConfig,cfg);
00060         mUseTemporalBPF=false;
00061         if(mConcreteConfig.HasAmount())
00062                 mAmount.DoControl(mConcreteConfig.GetAmount());
00063         else if(mConcreteConfig.HasBPFAmount()){
00064                 mAmount.DoControl(mConcreteConfig.GetBPFAmount().GetValue(0));
00065                 mUseTemporalBPF=true;}
00066         else
00067                 mAmount.DoControl(0);
00068         
00069         FrameInterpConfig tmpCfg;
00070         tmpCfg.SetHarmonic(mConcreteConfig.GetHarmonic());
00071         mPO_FrameInterpolator.Configure(tmpCfg);
00072 
00073         mPO_FrameInterpolator.Configure(FrameInterpConfig());
00074 
00075         return true;
00076 }
00077 
00078 bool SegmentSMSTimeStretch::ConcreteStop()
00079 {
00080         mPO_FrameInterpolator.Stop();
00081         return true;
00082 }
00083 
00084 bool SegmentSMSTimeStretch::ConcreteStart()
00085 {
00086         mSynthesisTime=0;
00087         mAnalysisTime=0;
00088         mCurrentInputFrame=-1;
00089         mnSynthesisFrames=0;
00090         mPO_FrameInterpolator.Start();
00091         mLeftFrame.SetCenterTime(-1);
00092         return true;
00093 }
00094 
00096 bool SegmentSMSTimeStretch::Do(const Frame& in, Frame& out)
00097 {
00098         TData interpFactor= (mAnalysisTime-mLeftFrame.GetCenterTime())/(mConcreteConfig.GetHopSize()/mConcreteConfig.GetSamplingRate());
00099         out.SetCenterTime(mSynthesisTime);
00100         mSynthesisTime+=(TData)mConcreteConfig.GetHopSize()/mConcreteConfig.GetSamplingRate();
00101         mnSynthesisFrames++;
00102         if(interpFactor>1)
00103         {
00104                 TData tmpCenterTime=out.GetCenterTime();
00105                 out=mLeftFrame;
00106                 out.SetCenterTime(tmpCenterTime);
00107                 return true;
00108         }
00109         if (interpFactor<0)
00110         {
00111                 TData tmpCenterTime=out.GetCenterTime();
00112                 out=in;
00113                 out.SetCenterTime(tmpCenterTime);
00114                 return true;
00115         }
00116 
00117         mPO_FrameInterpolator.mFrameInterpolationFactorCtl.DoControl(interpFactor);
00118         mLeftFrame.GetSpectralPeakArray().SetIsIndexUpToDate(true);
00119         mPO_FrameInterpolator.Do(in,mLeftFrame,out);
00120         
00121         return true;
00122 }
00123 
00124 
00125 bool SegmentSMSTimeStretch::Do(const Segment& in, Segment& out)
00126 {
00127         //Unused var: char test;
00128         if(mCurrentInputFrame>-1)
00129         {
00130                 while(mCurrentInputFrame<in.mCurrentFrameIndex&&!HaveFinished())
00131                 {
00132                         if(mConcreteConfig.GetUseBPF())
00133                         {
00134                                 UpdateControlValueFromBPF(((TData)mCurrentInputFrame)/in.GetnFrames());
00135                         }
00136                         TData previousAnalysisTime=mAnalysisTime;
00137                         UpdateTimeAndIndex(in);
00138                         if(mCurrentInputFrame>=in.mCurrentFrameIndex)
00139                         {
00140                                 UpdateControlValueFromBPF(((TData)mCurrentInputFrame)/in.GetnFrames());
00141                                 mCurrentInputFrame=in.mCurrentFrameIndex-2;
00142                                 if(mCurrentInputFrame<0) mCurrentInputFrame=0;//I don't know why but this happens sometimes
00143                                 mLeftFrame=in.GetFrame(mCurrentInputFrame);
00144                                 mAnalysisTime=previousAnalysisTime;
00145                                 return true;
00146                         }
00147                         Do(GetCurrentFrame(in),GetCurrentFrame(out));
00148                         CLAM_DEBUG_ASSERT(mCurrentInputFrame<in.mCurrentFrameIndex,"Error");
00149                         out.mCurrentFrameIndex++;
00150                 }
00151         }
00152         else mCurrentInputFrame++;
00153         return true;
00154 }
00155 
00156 void SegmentSMSTimeStretch::UpdateTimeAndIndex(const Segment& in)
00157 {
00158         mAnalysisTime+=(TData)mConcreteConfig.GetHopSize()*mAmount.GetLastValue()/mConcreteConfig.GetSamplingRate();
00159         while(mAnalysisTime>mLeftFrame.GetCenterTime()+mConcreteConfig.GetHopSize()/mConcreteConfig.GetSamplingRate()&&mCurrentInputFrame<=in.GetnFrames())
00160         {
00161                 mLeftFrame=in.GetFrame(mCurrentInputFrame);
00162                 mCurrentInputFrame++;
00163         }
00164 }
00165 
00166 const Frame& SegmentSMSTimeStretch::GetCurrentFrame(const Segment& in)
00167 {
00168         return in.GetFrame(mCurrentInputFrame);
00169 }
00170 
00171 
00172 Frame& SegmentSMSTimeStretch::GetCurrentFrame(Segment& out)
00173 {
00174         if(mnSynthesisFrames==out.GetnFrames())
00175                 out.AddFrame(out.GetFrame(out.GetnFrames()-1));
00176         return out.GetFrame(mnSynthesisFrames);
00177 }
00178 
00179 
00180 bool SegmentSMSTimeStretch::HaveFinished()
00181 {
00182         return mCurrentInputFrame>mInput->GetnFrames();
00183 }
00184 
00185 bool SegmentSMSTimeStretch::IsLastFrame()
00186 {
00187         bool isLast=HaveFinished();
00188         if(isLast)
00189         {
00190                 while(mOutput->GetnFrames()>mnSynthesisFrames-1)
00191                 {
00192                         mOutput->DeleteFrame(mOutput->GetnFrames()-1);
00193                 }
00194         }
00195         return isLast;
00196 }
00197 
00198 
00199 }
00200 
Generated by  doxygen 1.6.3