CLAM-Development
1.1
|
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