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 "SMSTimeStretch.hxx" 00023 #include "ProcessingFactory.hxx" 00024 00025 namespace CLAM 00026 { 00027 00028 namespace Hidden 00029 { 00030 static const char * metadata[] = { 00031 "key", "SMSTimeStretch", 00032 "category", "SMS Transformations", 00033 "description", "SMSTimeStretch", 00034 0 00035 }; 00036 00037 // static FactoryRegistrator<ProcessingFactory, SMSTimeStretch> reg = metadata; 00038 } 00039 00040 bool SMSTimeStretch::Do(const Frame& in, Frame& out) 00041 { 00042 return Do( in.GetSpectralPeakArray(), 00043 in.GetFundamental(), 00044 in.GetResidualSpec(), 00045 00046 out.GetSpectralPeakArray(), 00047 out.GetFundamental(), 00048 out.GetResidualSpec() 00049 ); 00050 } 00051 00052 // bool SMSTimeStretch::Do(const Segment& in, Segment& out) 00053 // { 00054 // //Unused var: char test; 00055 // if(mCurrentInputFrame>-1) 00056 // { 00057 // while(mCurrentInputFrame<in.mCurrentFrameIndex&&!HaveFinished()) 00058 // { 00059 // if(mConcreteConfig.GetUseBPF()) 00060 // { 00061 // UpdateControlValueFromBPF(((TData)mCurrentInputFrame)/in.GetnFrames()); 00062 // } 00063 // TData previousAnalysisTime=mAnalysisTime; 00064 // UpdateTimeAndIndex(in); 00065 // if(mCurrentInputFrame>=in.mCurrentFrameIndex) 00066 // { 00067 // UpdateControlValueFromBPF(((TData)mCurrentInputFrame)/in.GetnFrames()); 00068 // mCurrentInputFrame=in.mCurrentFrameIndex-2; 00069 // if(mCurrentInputFrame<0) mCurrentInputFrame=0;//I don't know why but this happens sometimes 00070 // mLeftFrame=in.GetFrame(mCurrentInputFrame); 00071 // mAnalysisTime=previousAnalysisTime; 00072 // return true; 00073 // } 00074 // Do(GetCurrentFrame(in),GetCurrentFrame(out)); 00075 // CLAM_DEBUG_ASSERT(mCurrentInputFrame<in.mCurrentFrameIndex,"Error"); 00076 // out.mCurrentFrameIndex++; 00077 // } 00078 // } 00079 // else mCurrentInputFrame++; 00080 // return true; 00081 // } 00082 bool SMSTimeStretch::Do( const SpectralPeakArray& inPeaks, 00083 const Fundamental& inFund, 00084 const Spectrum& inSpectrum, 00085 SpectralPeakArray& outPeaks, 00086 Fundamental& outFund, 00087 Spectrum& outSpectrum 00088 ) 00089 { 00090 // /**TODO: This method does not work if called directly! it must be called from the Segment overload*/ 00091 // bool SMSTimeStretch::Do(const Frame& in, Frame& out) 00092 00093 00094 //FIXME 00095 TData interpFactor; // = (mAnalysisTime-mLeftFrame.GetCenterTime()) / (mConfig.GetHopSize()/mConfig.GetSamplingRate()); 00096 // out.SetCenterTime(mSynthesisTime); 00097 00098 mSynthesisTime += (TData)mConfig.GetHopSize() / mConfig.GetSamplingRate(); 00099 00100 mnSynthesisFrames++; 00101 00102 // if (interpFactor>1) 00103 // { 00104 // TData tmpCenterTime = out.GetCenterTime(); 00105 // out = mLeftFrame; 00106 // out.SetCenterTime( tmpCenterTime ); 00107 // return true; 00108 // } 00109 00110 // if (interpFactor<0) 00111 // { 00112 // TData tmpCenterTime=out.GetCenterTime(); 00113 // out=in; 00114 // out.SetCenterTime(tmpCenterTime); 00115 // return true; 00116 // } 00117 00118 // mFrameInterpolator.mFrameInterpolationFactorCtl.DoControl( interpFactor ); 00119 // mLeftFrame.GetSpectralPeakArray().SetIsIndexUpToDate(true); 00120 // mFrameInterpolator.Do( in, mLeftFrame, out ); 00121 //TODO check morph interpolation 00122 // TData newPitch = (1. - interpFactor)*inFund1.GetFreq() + interpFactor*inFund2.GetFreq(); 00123 // if( Harmonic ) newPitch=0; 00124 // //Sets new fund freq 00125 // if (outFund.GetnCandidates()==0) 00126 // outFund.AddElem(newPitch,0); 00127 // else 00128 // outFund.SetFreq(0,newPitch); 00129 // outFund.SetnCandidates(1); 00130 00131 // mPeaksInterpolator.GetInControl("MagInterpolationFactor").DoControl(interpFactor); 00132 // mPeaksInterpolator.GetInControl("FreqInterpolationFactor").DoControl(alpha); 00133 // mPeaksInterpolator.GetInControl("PitchInterpolationFactor").DoControl(alpha); 00134 // mPeaksInterpolator.Do(inPeaks, inPeaks, outPeaks); 00135 00136 00137 //TODO separate alpha/interpolation value for peaks and residual???? 00138 00139 // outSpectrum = inSpectrum1; //FIXME asserts without this... 00140 // CLAM_DEBUG_ASSERT( inSpectrum1.GetSize()==inSpectrum2.GetSize(), "Expected two spectrums of the same size"); 00141 // mSpectrumInterpolator.GetInControl("InterpolationFactor").DoControl(alpha); 00142 00143 // TODO fix (and check SpectrumInterpolator bug... (add/fix const inputs) mSpectrumInterpolator.Do(inSpectrum1, inSpectrum2, outSpectrum);) 00144 // mSpectrumInterpolator.Do(const_cast<Spectrum&>(inSpectrum1), const_cast<Spectrum&>(inSpectrum2), outSpectrum); 00145 00146 return true; 00147 } 00148 00149 00150 // SMSTimeStretch::SMSTimeStretch() 00151 // :mFactor("Stretch Factor", this) 00152 // { 00153 // mSynthesisTime=0; 00154 // mAnalysisTime=0; 00155 // mCurrentInputFrame=-1; 00156 // Configure(SMSTimeStretchConfig()); 00157 // } 00158 00159 // SMSTimeStretch::SMSTimeStretch(const SegmentTransformationConfig &c) 00160 // : SegmentTransformation(c), 00161 // mFactor("Stretch Factor", this) 00162 // { 00163 // mSynthesisTime=0; 00164 // mAnalysisTime=0; 00165 // mCurrentInputFrame=-1; 00166 // Configure(c); 00167 // } 00168 00169 bool SMSTimeStretch::ConcreteConfigure(const ProcessingConfig& config) 00170 { 00171 CopyAsConcreteConfig( mConfig, config ); 00172 00173 // mUseTemporalBPF=false; 00174 // if(mConcreteConfig.HasAmount()) 00175 // mFactor.DoControl(mConcreteConfig.GetAmount()); 00176 // else if(mConcreteConfig.HasBPFAmount()){ 00177 // mFactor.DoControl(mConcreteConfig.GetBPFAmount().GetValue(0)); 00178 // mUseTemporalBPF=true;} 00179 // else 00180 // mAmount.DoControl(0); 00181 00182 // FrameInterpConfig tmpCfg; 00183 // tmpCfg.SetHarmonic(mConfig.GetHarmonic()); 00184 // mFrameInterpolator.Configure(tmpCfg); 00185 // mFrameInterpolator.Configure(FrameInterpConfig()); 00186 00187 return true; 00188 } 00189 00190 //FIXME 00191 bool SMSTimeStretch::ConcreteStop() 00192 { 00193 // mFrameInterpolator.Stop(); 00194 return true; 00195 } 00196 00197 //FIXME 00198 bool SMSTimeStretch::ConcreteStart() 00199 { 00200 mSynthesisTime=0; 00201 mAnalysisTime=0; 00202 // mCurrentInputFrame=-1; 00203 mnSynthesisFrames=0; 00204 // mFrameInterpolator.Start(); 00205 mLeftFrame.SetCenterTime(-1); 00206 return true; 00207 } 00208 00209 // void SMSTimeStretch::UpdateTimeAndIndex(const Segment& in) 00210 // { 00211 // mAnalysisTime+=(TData)mConcreteConfig.GetHopSize()*mFactor.GetLastValue()/mConcreteConfig.GetSamplingRate(); 00212 // while(mAnalysisTime>mLeftFrame.GetCenterTime()+mConcreteConfig.GetHopSize()/mConcreteConfig.GetSamplingRate()&&mCurrentInputFrame<=in.GetnFrames()) 00213 // { 00214 // mLeftFrame=in.GetFrame(mCurrentInputFrame); 00215 // mCurrentInputFrame++; 00216 // } 00217 // } 00218 // 00219 // const Frame& SMSTimeStretch::GetCurrentFrame(const Segment& in) 00220 // { 00221 // return in.GetFrame(mCurrentInputFrame); 00222 // } 00223 // 00224 // 00225 // Frame& SMSTimeStretch::GetCurrentFrame(Segment& out) 00226 // { 00227 // if(mnSynthesisFrames==out.GetnFrames()) 00228 // out.AddFrame(out.GetFrame(out.GetnFrames()-1)); 00229 // return out.GetFrame(mnSynthesisFrames); 00230 // } 00231 // 00232 // 00233 // bool SMSTimeStretch::HaveFinished() 00234 // { 00235 // return mCurrentInputFrame>mInput->GetnFrames(); 00236 // } 00237 // 00238 // bool SMSTimeStretch::IsLastFrame() 00239 // { 00240 // bool isLast=HaveFinished(); 00241 // if(isLast) 00242 // { 00243 // while(mOutput->GetnFrames()>mnSynthesisFrames-1) 00244 // { 00245 // mOutput->DeleteFrame(mOutput->GetnFrames()-1); 00246 // } 00247 // } 00248 // return isLast; 00249 // } 00250 00251 00252 } 00253