PhaseManagement.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 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 "PhaseManagement.hxx"
00023 #include "Err.hxx"
00024 #include "SpectralPeakArray.hxx"
00025 
00026 namespace CLAM
00027 {
00028 
00029 
00030 
00031 PhaseManagement::PhaseManagement():
00032         mCurrentTime("CurrentTime",this),mCurrentPitch("CurrentPitch",this)
00033 {
00034         Configure(PhaseManagementConfig());
00035         Init();
00036 }
00037 
00038 PhaseManagement::PhaseManagement(PhaseManagementConfig& c):
00039         mCurrentTime("CurrentTime",this),mCurrentPitch("CurrentPitch",this)
00040 {
00041         Configure(c);
00042         Init();
00043 }
00044 
00045 bool PhaseManagement::ConcreteConfigure(const ProcessingConfig& c)
00046 {
00047         CopyAsConcreteConfig(mConfig, c);
00048         return true;
00049 }
00050 
00051 void PhaseManagement::Init()
00052 {
00053         mRandomPhase.Resize(mConfig.GetMaxSines());
00054         mRandomPhase.SetSize(mConfig.GetMaxSines());
00055                 
00056         mFrameTime=0;
00057         mLastPeriodTime=0.0;
00058         mNextPeriodTime=0.0;
00059         mLastFundFreq=0.0;
00060 
00061         mLastPeakArray.AddPhaseBuffer();
00062         mLastPeakArray.AddBinWidthBuffer();
00063         mLastPeakArray.AddBinPosBuffer();
00064         mLastPeakArray.AddIndexArray();
00065 
00066         mLastPeakArray.UpdateData();
00067         mLastPeakArray.SetScale(EScale::eLog);
00068         // init
00069         GenerateRandomPhases(mRandomPhase);
00070         GenerateRandomPhases(mLastPeakArray.GetPhaseBuffer());
00071 
00072         mLastPeakArray.SetIsIndexUpToDate(true);
00073 
00074 }
00075 
00076 
00077 PhaseManagement::~PhaseManagement()
00078 {
00079 
00080 }
00081 
00082 bool PhaseManagement::Do(SpectralPeakArray& in)
00083 {
00084         switch(mConfig.GetType())
00085         {
00086                 case (EPhaseGeneration::eAlign):
00087                 {
00088                         DoPhaseAlignment(in);
00089                         break;
00090                 }
00091                 case (EPhaseGeneration::eContinuation):
00092                 {
00093                         DoPhaseContinuation(in);
00094                         break;
00095                 }
00096                 case (EPhaseGeneration::eRandom):
00097                 {
00098                         DoRandomPhases(in);
00099                         break;
00100                 }
00101                 case (EPhaseGeneration::eNone):
00102                 {
00103                         break;
00104                 }
00105         }
00106         return true;
00107 }
00108 
00109 bool PhaseManagement::Do(Frame& currentFrame)
00110 {
00111         mCurrentTime.DoControl(currentFrame.GetCenterTime());
00112         mCurrentPitch.DoControl(currentFrame.GetFundamental().GetFreq(0));
00113         
00114         return Do(currentFrame.GetSpectralPeakArray());
00115 }
00116 
00117 //----------------------------------------------------------------------------//
00118 void
00119 PhaseManagement::ResetPhaseAlignment()
00120 {
00121         // reset values before starting new thesis thread
00122         mLastPeriodTime = 0.0;
00123         mNextPeriodTime = 0.0;
00124         mLastFundFreq = 0.0;
00125 }
00126 //----------------------------------------------------------------------------//
00127 
00128 void
00129 PhaseManagement::DoPhaseAlignment(SpectralPeakArray& peakArray)
00130 {
00131 
00132         TIndex numPeaks = peakArray.GetnPeaks();
00133         double                                  phase,freq;
00134   
00135         TData t=mCurrentTime.GetLastValue();
00136         //phaseAlignment 
00137         if (mCurrentPitch.GetLastValue()>0)     // use phase align only when mCurrentPitch.GetLastValue() is existing 
00138         {
00139                 double newPeriodDuration = 1/mCurrentPitch.GetLastValue();
00140                 
00141                 if ((mLastPeriodTime!=0.0) && (mLastPeriodTime<mCurrentTime.GetLastValue()))
00142                 {
00143                         double lastPeriodDuration = mNextPeriodTime - mLastPeriodTime;
00144                         mNextPeriodTime = mLastPeriodTime + newPeriodDuration;
00145                         double averagePeriodDuration = 0.5*lastPeriodDuration + 0.5*newPeriodDuration;
00146 
00147                         double timeDiff = t-mLastPeriodTime;
00148 
00149                         TIndex nPeriodsElapsed = (TIndex)floor(timeDiff/averagePeriodDuration);                 
00150                 
00151                         if (timeDiff-nPeriodsElapsed*averagePeriodDuration > newPeriodDuration-mFrameTime*0.5)
00152                                 nPeriodsElapsed++;
00153                         
00154                         double timePeriodDiff = timeDiff - nPeriodsElapsed*averagePeriodDuration;
00155                         
00156                         double thPeriodPosition = (timeDiff-nPeriodsElapsed*averagePeriodDuration)/newPeriodDuration;
00157                         
00158                         timePeriodDiff = thPeriodPosition*newPeriodDuration;
00159                         
00160                         for (int i = 0;i<numPeaks;i++)
00161                         {
00162                                 double phase1 = peakArray.GetPhase(i);
00163                                 freq    = peakArray.GetFreq(i);
00164                                 phase = phase1+TWO_PI*freq*timePeriodDiff;                      
00165                                 // in orig. sms we distinguish here perfect harmonic/not perfect harmonic
00166                                 phase = phase - floor(phase/TWO_PI)*TWO_PI;     // phase wrapping
00167                                 peakArray.SetPhase(i,TData(phase));
00168                         }
00169                         if (nPeriodsElapsed > 0)
00170                         {
00171                                 mLastPeriodTime += nPeriodsElapsed*averagePeriodDuration;
00172                                 mNextPeriodTime = mLastPeriodTime + newPeriodDuration;
00173                         }
00174                 }
00175                 else
00176                 {
00177                         mLastPeriodTime = t;
00178                         mNextPeriodTime = t + newPeriodDuration;
00179                 }
00180         }                        
00181         else
00182         {
00183                 mLastPeriodTime = 0.0;
00184                 mNextPeriodTime = 0.0;  
00185         }
00186         mLastPeakArray.SetIsIndexUpToDate(true);
00187 
00188 }
00189   
00190 //----------------------------------------------------------------------------//
00191 
00192 void PhaseManagement::DoRandomPhases(SpectralPeakArray& peakArray)
00193 {
00194         //MTG::SpectralPeakArray* peakArray = thFrame.GetPeakArrayPtr();
00195         TIndex numPeaks = peakArray.GetnPeaks();
00196         
00197         int                                                     i;
00198         double                                  phase,freq;
00199                 
00200         DataArray& lastPhase=mLastPeakArray.GetPhaseBuffer();
00201         DataArray& lastFreq=mLastPeakArray.GetFreqBuffer();
00202         int nPeaks=peakArray.GetnPeaks();
00203         
00204         lastPhase.Resize(nPeaks);
00205         lastPhase.SetSize(nPeaks);
00206         lastFreq.Resize(nPeaks);
00207         lastFreq.SetSize(nPeaks);
00208 
00209         for     (i=0;i<numPeaks;i++)
00210         {
00211                 //phase = peakArray.GetPhase(i);
00212                 freq  = peakArray.GetFreq(i);
00213                 
00214                 //find peak corresponding to current track
00215                 TIndex prevPos =peakArray.GetIndex(i);
00216                 
00217                 // use a set of random phases and calculate each time the correct phase..
00218                 if (prevPos == -1||prevPos>mLastPeakArray.GetnPeaks()) // new track...
00219                 {
00220                         phase = mRandomPhase[i];
00221                         peakArray.SetPhase(i,TData(phase));
00222 
00223                         lastPhase[i]=phase;
00224                         lastFreq[i]=freq;
00225                         /*SpectralPeak tmpPeak;
00226                         mLastPeakArray.InitPeak(tmpPeak);
00227                         tmpPeak.SetPhase(TData(phase));
00228                         tmpPeak.SetFreq(TData(phase));
00229                         mLastPeakArray.AddSpectralPeak(tmpPeak);*/
00230                 }
00231                 else    // track is existing, calculate according phase..
00232                 {
00233                         SpectralPeak lastPeak=mLastPeakArray.GetSpectralPeak(prevPos);
00234                         phase = lastPeak.GetPhase() + TWO_PI*((lastPeak.GetFreq()+freq)*0.5*mFrameTime);
00235                         
00236                         //phase = phase - floor(phase/TWO_PI)*TWO_PI;
00237                         while (phase >= TWO_PI) phase = phase -TWO_PI;          // other way..
00238                         peakArray.SetPhase(i,TData(phase));
00239                         lastPhase[prevPos]=TData(phase);
00240                         lastFreq[prevPos]=TData(phase);
00241                 }       
00242         }
00243         mLastPeakArray.SetIsIndexUpToDate(true);
00244 
00245    
00246 }
00247 
00248 
00249 void PhaseManagement::DoPhaseContinuation(SpectralPeakArray& p)
00250 {
00251         int i;
00252         TData t=mCurrentTime.GetLastValue();
00253         int nPeaks = p.GetnPeaks();
00254         DataArray& lastPhaseBuffer = mLastPeakArray.GetPhaseBuffer();
00255         DataArray& lastFreqBuffer = mLastPeakArray.GetFreqBuffer();
00256         DataArray& currentPhaseBuffer = p.GetPhaseBuffer();
00257         DataArray& currentFreqBuffer = p.GetFreqBuffer();
00258         
00259         TData timeDifference = t-mFrameTime;
00260         TData halfPI= TData(TWO_PI)*TData(0.5);
00261         
00262         TData halfPITimeDifference = timeDifference*halfPI;
00263         TData twoPITimeDifference = TData(TWO_PI)*timeDifference;
00264         
00265         for(i=0;i<nPeaks;i++)
00266         {
00267                 TIndex currentIndex=p.GetIndex(i);
00268                 TIndex lastPos=mLastPeakArray.GetPositionFromIndex(currentIndex);
00269                 if(lastPos!=-1)
00270                 {
00271                         //SpectralPeak tmpPeak=mLastPeakArray.GetSpectralPeak(lastPos);
00272                         //p.SetPhase(i,tmpPeak.GetPhase()+TData(TWO_PI)*TData(0.5)*(tmpPeak.GetFreq()+p.GetFreq(i))*(t-mFrameTime));
00273                         currentPhaseBuffer[i] = lastPhaseBuffer[lastPos]+
00274                                 halfPITimeDifference*(lastFreqBuffer[lastPos]+currentFreqBuffer[i]);
00275                         
00276                 }
00277                 else
00278                 {
00279                         //p.SetPhase(i,TData(TWO_PI)*p.GetFreq(i)*(t-mFrameTime));
00280                         currentPhaseBuffer[i] = currentFreqBuffer[i]*twoPITimeDifference;
00281                 }
00282                 //p.SetPhase(i,p.GetPhase(i)-floor((TData)(p.GetPhase(i)/TData(TWO_PI)))*TData(TWO_PI));
00283                 currentPhaseBuffer[i] = currentPhaseBuffer[i]-floor((TData)(currentPhaseBuffer[i]/TData(TWO_PI)))*TData(TWO_PI);
00284         }
00285         mFrameTime=t;
00286         mLastPeakArray=p;
00287         mLastPeakArray.SetIsIndexUpToDate(true);
00288 }
00289    
00290 //----------------------------------------------------------------------------//
00291 void
00292 PhaseManagement::GenerateRandomPhases(DataArray& a)
00293 {
00294         for (int i = 0; i<a.Size();i++)
00295         {
00296                 a[i] = rand()/TData(RAND_MAX*TWO_PI);
00297         }
00298 }
00299 //----------------------------------------------------------------------------//
00300 void
00301 PhaseManagement::SetLastPhasesAndFreqs(SpectralPeakArray& peakArray)
00302 {
00303         DataArray& lastPhase=mLastPeakArray.GetPhaseBuffer();
00304         DataArray& lastFreq=mLastPeakArray.GetFreqBuffer();
00305         DataArray& currentPhase= peakArray.GetPhaseBuffer();
00306         DataArray& currentFreq= peakArray.GetFreqBuffer();
00307         int nPeaks=peakArray.GetnPeaks();
00308 
00309         lastPhase.Resize(nPeaks);
00310         lastPhase.SetSize(nPeaks);
00311         lastFreq.Resize(nPeaks);
00312         lastFreq.SetSize(nPeaks);
00313 
00314         for (int i=0;i<nPeaks;i++)
00315         {
00316                 lastPhase[i] = currentPhase[i];
00317                 lastFreq[i]  = currentFreq[i];
00318         }
00319         mLastPeakArray.SetIsIndexUpToDate(true);
00320 
00321 }
00322 
00323 } // namespace CLAM
00324 

Generated on Tue Aug 12 22:33:43 2008 for CLAM by  doxygen 1.5.5