|
CLAM-Development
1.3
|
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
1.7.6.1