SegmentSMSMorph.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 #include "SegmentSMSMorph.hxx"
00022 #include "ProcessingFactory.hxx"
00023 #include "SpectrumConfig.hxx"
00024 
00025 namespace CLAM
00026 {
00027 
00028 namespace Hidden
00029 {
00030         static const char * metadata[] = {
00031                 "key", "SegmentSMSMorph",
00032 //              "category", "SMS Transformations",
00033                 "description", "SegmentSMSMorph",
00034                 0
00035         };
00036         static FactoryRegistrator<ProcessingFactory, SegmentSMSMorph> reg = metadata;
00037 }
00038 
00039 SegmentSMSMorph::SegmentSMSMorph():
00040         mHybBPF("MorphFactor",this),
00041         mSynchronizeTime("Time", this),
00042         mHybSinAmp("SinAmp", this),
00043         mHybSinSpectralShape("SinShape", this),
00044         mHybSinShapeW1("SinShapeW1", this),
00045         mHybSinShapeW2("SinShapeW2", this),
00046         mHybPitch("Pitch", this),
00047         mHybSinFreq("SinFreq", this),
00048         mHybResAmp("ResAmp", this),
00049         mHybResSpectralShape("ResShape", this),
00050         mHybResShapeW1("ResShapeW1", this),
00051         mHybResShapeW2("ResShapeW2", this),
00052         mpInput2(0)
00053         
00054 {
00055                 mHaveInternalSegment=false;
00056                 mUseTemporalBPF = true;
00057                 mUseSinSpectralShape=false;
00058                 mUseGlobalFactor=false;
00059                 mUseSynchronizeTime=false;
00060                 mUseSinAmp=false;
00061                 mUsePitch=false;
00062                 mUseSinFreq=false;
00063                 mUseResAmp=false;
00064                 mUseResSpectralShape=false;
00065                 mUseSinSpectralShape=false;
00066 }
00067 
00068 SegmentSMSMorph::SegmentSMSMorph(const SegmentSMSMorphConfig &c):
00069         mHybBPF("MorphFactor",this),
00070         mSynchronizeTime("Time", this),
00071         mHybSinAmp("SinAmp", this),
00072         mHybSinSpectralShape("SinShape", this),
00073         mHybSinShapeW1("SinShapeW1", this),
00074         mHybSinShapeW2("SinShapeW2", this),
00075         mHybPitch("Pitch", this),
00076         mHybSinFreq("SinFreq", this),
00077         mHybResAmp("ResAmp", this),
00078         mHybResSpectralShape("ResShape", this),
00079         mHybResShapeW1("ResShapeW1", this),
00080         mHybResShapeW2("ResShapeW2", this),
00081         mpInput2(0)
00082 
00083 {
00084         mHaveInternalSegment=false;
00085         mUseTemporalBPF = true;
00086 
00087         mUseSinSpectralShape=false;
00088         mUseGlobalFactor=false;
00089         mUseSynchronizeTime=false;
00090         mUseSinAmp=false;
00091         mUsePitch=false;
00092         mUseSinFreq=false;
00093         mUseResAmp=false;
00094         mUseResSpectralShape=false;
00095         mUseSinSpectralShape=false;
00096         Configure(c);
00097 }
00098 
00099 bool SegmentSMSMorph::ConcreteConfigure(const ProcessingConfig& c) 
00100 {
00101         CopyAsConcreteConfig(mConfig,c);
00102         mHaveInternalSegment=false;
00103         
00104         if(mConfig.HasFileName())
00105         {
00106                 if(LoadSDIF(mConfig.GetFileName(),mSegment))
00107                 {
00108                         mpInput2=&mSegment;
00109                         mHaveInternalSegment=true;
00110                 }
00111         }
00112 
00113         SpecTypeFlags type;
00114         SpectrumConfig cfg;
00115         type.bMagPhase=false;
00116         type.bMagPhaseBPF=true;
00117         cfg.SetType(type);
00118         cfg.SetSpectralRange(mConfig.GetSamplingRate()/2);
00119 
00120         mUseSinSpectralShape=mConfig.GetUseSpectralShapes();
00121         mUseResSpectralShape=mConfig.GetUseSpectralShapes();
00122 
00123         
00124         InitializeFactorsToUse();
00125 
00126         FrameInterpConfig frIntCfg;
00127 
00128         if(mUseSinSpectralShape)
00129         {
00130                 frIntCfg.SetUseSpectralShape(true);
00131                 mPO_FrameInterpolator.AttachSpectralShape(mSpectralShape);
00132                 mSpectralShape.Configure(cfg);
00133                 mResSpectralShape.Configure(cfg);
00134         }
00135 
00136         CLAM_ASSERT( mPO_FrameInterpolator.Configure(frIntCfg),
00137                                  "Failed to configure Frame interpolator in SegmentSMSMorph::ConcreteConfigure" );
00138         
00139         return UpdateControlValueFromBPF(0);
00140 }
00141 
00142 bool SegmentSMSMorph::ConcreteStart()
00143 {
00144         mPO_FrameInterpolator.Start();
00145         return true;
00146 }
00147 
00148 void SegmentSMSMorph::UpdateFrameInterpolatorFactors(bool useFrameFactor=false)
00149 {
00150         if(useFrameFactor)
00151         {
00152                 mPO_FrameInterpolator.mFrameInterpolationFactorCtl.DoControl(mHybBPF.GetLastValue());
00153         }
00154         else//No Global Factor
00155         {
00156                 mPO_FrameInterpolator.mMagInterpolationFactorCtl.DoControl(mHybSinAmp.GetLastValue());
00157                 mPO_FrameInterpolator.mFreqInterpolationFactorCtl.DoControl(mHybSinFreq.GetLastValue());
00158                 mPO_FrameInterpolator.mPitchInterpolationFactorCtl.DoControl(mHybPitch.GetLastValue());
00159                 mPO_FrameInterpolator.mResidualInterpolationFactorCtl.DoControl(mHybResAmp.GetLastValue());
00160         }
00161 }
00162 
00163 bool SegmentSMSMorph::Do(const Frame& in1, Frame& out)
00164 {
00165         TSize nFrames2=mpInput2->GetnFrames();
00166         TData synchroTimeFactor=mSynchronizeTime.GetLastValue()*nFrames2;
00167         
00168         if(mSynchronizeTime.GetLastValue()<0.0001||mSynchronizeTime.GetLastValue()>0.9999)
00169         {
00170                 //it means we are at the boudaries of segment to morph
00171                 out=in1;
00172 
00173                 return true;
00174         }
00175 
00176         Frame tempFrame2;
00177 
00178         //With Frame Interpolation
00179         if(mConfig.GetInterpolateFrame())
00180         {
00181                 FindInterpolatedFrameFromSegment2Morph(tempFrame2);
00182                 //Morphing
00183                 UpdateFrameInterpolatorFactors();
00184                 mPO_FrameInterpolator.Do(in1,tempFrame2,out);
00185 
00186         }
00187         //Without Frame Interpolation
00188         else
00189         {
00190                 UpdateFrameInterpolatorFactors();
00191                 mPO_FrameInterpolator.Do(in1,mpInput2->GetFrame(int(synchroTimeFactor)),out);
00192 
00193         }
00194                                         
00195         return true;
00196 
00197 
00198 }
00199 
00200 bool SegmentSMSMorph::FindInterpolatedFrameFromSegment2Morph(Frame& interpolatedFrame)
00201 {
00202         TSize nFrames2=mpInput2->GetnFrames();
00203         TData synchroTimeFactor=mSynchronizeTime.GetLastValue()*nFrames2;
00204         
00205         //Initializes interpolated frame 
00206         interpolatedFrame=mpInput2->GetFrame(mpInput2->mCurrentFrameIndex);
00207         //Interpolation data
00208         int frameNo1=int(floor(synchroTimeFactor));
00209         int frameNo2=int(ceil(synchroTimeFactor));
00210         
00211         //Interpolating
00212         TData frameFactor=synchroTimeFactor-frameNo1;
00213         mHybBPF.DoControl(frameFactor);
00214         UpdateFrameInterpolatorFactors(true);
00215         return mPO_FrameInterpolator.Do(mpInput2->GetFrame(frameNo1) , mpInput2->GetFrame(frameNo2) , interpolatedFrame);                       
00216 }
00217 
00218 bool SegmentSMSMorph::Do(const Segment& in1, Segment& out)
00219 {
00220         if(!mHaveInternalSegment) return false;
00221         return SegmentTransformation::Do(in1,out);
00222 }
00223 
00224 bool SegmentSMSMorph::Do(const Segment& in1,Segment& in2, Segment& out)
00225 {
00226         if(!mpInput2)
00227                 mpInput2 = &in2;
00228         mHaveInternalSegment = true;
00229         return Do(in1,out);
00230 }
00231 
00232 bool SegmentSMSMorph::UpdateControlValueFromBPF(TData pos)
00233 {
00234         bool ret=true;
00235 
00236         TData globalFactor=0;
00237         
00238         //Warning, maybe controls that are not used should be initialize to something sensible (does not affect)
00239         
00240         if(mUseGlobalFactor)
00241         {
00242                 globalFactor=mConfig.GetHybBPF().GetValue(pos);
00243                 mHybBPF.DoControl(globalFactor);
00244         }
00245         else
00246                 ret=false;
00247         if(mUseSynchronizeTime)
00248         {
00249                 pos=mConfig.GetSynchronizeTime().GetValue(pos);
00250                 mSynchronizeTime.DoControl(pos);
00251         }
00252 
00253         if(mUseSinAmp)
00254                 mHybSinAmp.DoControl(mConfig.GetHybSinAmp().GetValue(pos));
00255         else
00256                 mHybSinAmp.DoControl(globalFactor);
00257 
00258         if(mUsePitch)
00259                 mHybPitch.DoControl(mConfig.GetHybPitch().GetValue(pos));
00260         else
00261                 mHybPitch.DoControl(globalFactor);
00262 
00263         if(mUseSinFreq)
00264                 mHybSinFreq.DoControl(mConfig.GetHybSinFreq().GetValue(pos));
00265         else
00266                 mHybSinFreq.DoControl(globalFactor);
00267 
00268         if(mUseResAmp)
00269                 mHybResAmp.DoControl(mConfig.GetHybResAmp().GetValue(pos));
00270         else
00271                 mHybResAmp.DoControl(globalFactor);
00272 
00273         //Updating spectral shapes
00274         if(mUseResSpectralShape)
00275         {
00276                 mHybResSpectralShape.DoControl(mConfig.GetHybResSpectralShape().GetValue(pos));
00277                 UpdateSpectralShape(mConfig.GetHybResShapeW1(),mConfig.GetHybResShapeW2(),mHybResSpectralShape.GetLastValue(),mResSpectralShape);
00278         }
00279         if(mUseSinSpectralShape)
00280         {
00281                 mHybSinSpectralShape.DoControl(mConfig.GetHybSinSpectralShape().GetValue(pos));
00282                 UpdateSpectralShape(
00283                                 mConfig.GetHybSinShapeW1(),
00284                                 mConfig.GetHybSinShapeW2(),
00285                                 mHybSinSpectralShape.GetLastValue(),
00286                                 mSpectralShape );
00287         }
00288 
00289         return ret;
00290 }
00291 
00292 void SegmentSMSMorph::InitializeFactorsToUse()
00293 {
00294         if(mConfig.HasHybBPF())
00295                 mUseGlobalFactor=true;
00296         if(mConfig.HasSynchronizeTime() && mConfig.GetSynchronizeTime().Size() )
00297                 mUseSynchronizeTime=true;
00298         if(mConfig.HasHybSinAmp() && mConfig.GetHybSinAmp().Size())
00299                 mUseSinAmp=true;
00300         if(mConfig.HasHybPitch() && mConfig.GetHybPitch().Size() )
00301                 mUsePitch=true;
00302         if(mConfig.HasHybSinFreq() && mConfig.GetHybSinFreq().Size())
00303                 mUseSinFreq=true;
00304         if(mConfig.HasHybResAmp() && mConfig.GetHybResAmp().Size() )
00305                 mUseResAmp=true;
00306         if(mConfig.GetUseSpectralShapes())
00307         {
00308                         mUseResSpectralShape=true;
00309                         mUseResAmp=false;
00310                         mUseSinSpectralShape=true;
00311                         mUseSinAmp=false;
00312         }
00313 
00314 }
00315 
00316 void SegmentSMSMorph::UpdateSpectralShape(const BPF& weightBPF1, const BPF& weightBPF2,TData interpFactor, Spectrum& spectralShape)
00317 {
00318         BPF spectralShapeBPF;
00319         TData spectralRange=spectralShape.GetSpectralRange();
00320         //we will always add as many points as possible, so we take weightBPF with maximum points
00321         int nPoints;
00322         bool usingFirst=false;
00323         if(weightBPF1.Size()>weightBPF2.Size())
00324         {
00325                 nPoints=weightBPF1.Size();
00326                 usingFirst=true;
00327         }
00328         else nPoints=weightBPF2.Size();
00329         int i;
00330         TData xValue,yValue;
00331         if(usingFirst)
00332         {
00333                 for(i=0;i<nPoints;i++)
00334                 {
00335                         xValue=weightBPF1.GetXValue(i);
00336                         yValue=weightBPF1.GetValueFromIndex(i)*interpFactor+weightBPF2.GetValue(xValue)*(1-interpFactor);
00337                         xValue*=spectralRange;
00338                         spectralShapeBPF.Insert(xValue,yValue);
00339                 }
00340         }
00341         else
00342         {
00343                 for(i=0;i<nPoints;i++)
00344                 {
00345                         xValue=weightBPF2.GetXValue(i);
00346                         yValue=weightBPF2.GetValueFromIndex(i)*interpFactor+weightBPF1.GetValue(xValue)*(1-interpFactor);
00347                         xValue*=spectralRange;
00348                         spectralShapeBPF.Insert(xValue,yValue);
00349                 }
00350         }
00351         spectralShape.SetMagBPF(spectralShapeBPF);
00352         spectralShape.SetSize(spectralShapeBPF.Size());
00353 
00354 }
00355 
00356 bool SegmentSMSMorph::LoadSDIF( std::string fileName, Segment& segment )
00357 {
00358         SDIFInConfig cfg;
00359         cfg.SetMaxNumPeaks( 100 );
00360         cfg.SetFileName( fileName );
00361         cfg.SetEnableResidual( true );
00362         if(!mSDIFReader.Configure( cfg )) return false;//wrong filename or non-existing sdif
00363                 
00364         segment.AddAll(  );
00365         segment.UpdateData(  );
00366         
00367         try{
00368                 mSDIFReader.Start(  );}
00369         catch (Err)
00370         {
00371                 return false;//wrong filename or non-existing sdif
00372         }
00373         while( mSDIFReader.Do(segment) ) {  }
00374         mSDIFReader.Stop(  );
00375         
00376         return true;
00377 }
00378 
00379 void SegmentSMSMorph::SetSegmentToMorph(Segment& segmentToMorph)
00380 {
00381         mpInput2 = &segmentToMorph;
00382         mHaveInternalSegment=true;
00383 }
00384 
00385 
00386 }
00387 
Generated by  doxygen 1.6.3