SegmentSMSTimeStretch.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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;
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