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