CLAM-Development  1.4.0
PhaseManagement.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "PhaseManagement.hxx"
23 #include "Err.hxx"
24 #include "SpectralPeakArray.hxx"
25 
26 namespace CLAM
27 {
28 
30  : mCurrentTime("CurrentTime",this)
31  , mCurrentPitch("CurrentPitch",this)
32 {
33  Configure(c);
34  Init();
35 }
36 
38 {
39  CopyAsConcreteConfig(mConfig, c);
40  return true;
41 }
42 
44 {
45  mRandomPhase.Resize(mConfig.GetMaxSines());
46  mRandomPhase.SetSize(mConfig.GetMaxSines());
47 
48  mFrameTime=0;
49  mLastPeriodTime=0.0;
50  mNextPeriodTime=0.0;
51  mLastFundFreq=0.0;
52 
53  mLastPeakArray.AddPhaseBuffer();
54  mLastPeakArray.AddBinWidthBuffer();
55  mLastPeakArray.AddBinPosBuffer();
56  mLastPeakArray.AddIndexArray();
57 
58  mLastPeakArray.UpdateData();
59  mLastPeakArray.SetScale(EScale::eLog);
60  // init
61  GenerateRandomPhases(mRandomPhase);
62  GenerateRandomPhases(mLastPeakArray.GetPhaseBuffer());
63 
64  mLastPeakArray.SetIsIndexUpToDate(true);
65 
66 }
67 
68 
70 {
71 
72 }
73 
75 {
76  switch(mConfig.GetType())
77  {
79  {
80  DoPhaseAlignment(in);
81  break;
82  }
84  {
86  break;
87  }
89  {
90  DoRandomPhases(in);
91  break;
92  }
94  {
95  break;
96  }
97  }
98  return true;
99 }
100 
101 bool PhaseManagement::Do(Frame& currentFrame)
102 {
103  mCurrentTime.DoControl(currentFrame.GetCenterTime());
104  mCurrentPitch.DoControl(currentFrame.GetFundamental().GetFreq(0));
105 
106  return Do(currentFrame.GetSpectralPeakArray());
107 }
108 
109 //----------------------------------------------------------------------------//
110 void
112 {
113  // reset values before starting new thesis thread
114  mLastPeriodTime = 0.0;
115  mNextPeriodTime = 0.0;
116  mLastFundFreq = 0.0;
117 }
118 //----------------------------------------------------------------------------//
119 
120 void
122 {
123 
124  TIndex numPeaks = peakArray.GetnPeaks();
125  double phase,freq;
126 
128  //phaseAlignment
129  if (mCurrentPitch.GetLastValue()>0) // use phase align only when mCurrentPitch.GetLastValue() is existing
130  {
131  double newPeriodDuration = 1/mCurrentPitch.GetLastValue();
132 
133  if ((mLastPeriodTime!=0.0) && (mLastPeriodTime<mCurrentTime.GetLastValue()))
134  {
135  double lastPeriodDuration = mNextPeriodTime - mLastPeriodTime;
136  mNextPeriodTime = mLastPeriodTime + newPeriodDuration;
137  double averagePeriodDuration = 0.5*lastPeriodDuration + 0.5*newPeriodDuration;
138 
139  double timeDiff = t-mLastPeriodTime;
140 
141  TIndex nPeriodsElapsed = (TIndex)floor(timeDiff/averagePeriodDuration);
142 
143  if (timeDiff-nPeriodsElapsed*averagePeriodDuration > newPeriodDuration-mFrameTime*0.5)
144  nPeriodsElapsed++;
145 
146  double timePeriodDiff = timeDiff - nPeriodsElapsed*averagePeriodDuration;
147 
148  double thPeriodPosition = (timeDiff-nPeriodsElapsed*averagePeriodDuration)/newPeriodDuration;
149 
150  timePeriodDiff = thPeriodPosition*newPeriodDuration;
151 
152  for (int i = 0;i<numPeaks;i++)
153  {
154  double phase1 = peakArray.GetPhase(i);
155  freq = peakArray.GetFreq(i);
156  phase = phase1+TWO_PI*freq*timePeriodDiff;
157  // in orig. sms we distinguish here perfect harmonic/not perfect harmonic
158  phase = phase - floor(phase/TWO_PI)*TWO_PI; // phase wrapping
159  peakArray.SetPhase(i,TData(phase));
160  }
161  if (nPeriodsElapsed > 0)
162  {
163  mLastPeriodTime += nPeriodsElapsed*averagePeriodDuration;
164  mNextPeriodTime = mLastPeriodTime + newPeriodDuration;
165  }
166  }
167  else
168  {
169  mLastPeriodTime = t;
170  mNextPeriodTime = t + newPeriodDuration;
171  }
172  }
173  else
174  {
175  mLastPeriodTime = 0.0;
176  mNextPeriodTime = 0.0;
177  }
178  mLastPeakArray.SetIsIndexUpToDate(true);
179 
180 }
181 
182 //----------------------------------------------------------------------------//
183 
185 {
186  //MTG::SpectralPeakArray* peakArray = thFrame.GetPeakArrayPtr();
187  TIndex numPeaks = peakArray.GetnPeaks();
188 
189  int i;
190  double phase,freq;
191 
192  DataArray& lastPhase=mLastPeakArray.GetPhaseBuffer();
193  DataArray& lastFreq=mLastPeakArray.GetFreqBuffer();
194  int nPeaks=peakArray.GetnPeaks();
195 
196  lastPhase.Resize(nPeaks);
197  lastPhase.SetSize(nPeaks);
198  lastFreq.Resize(nPeaks);
199  lastFreq.SetSize(nPeaks);
200 
201  for (i=0;i<numPeaks;i++)
202  {
203  //phase = peakArray.GetPhase(i);
204  freq = peakArray.GetFreq(i);
205 
206  //find peak corresponding to current track
207  TIndex prevPos =peakArray.GetIndex(i);
208 
209  // use a set of random phases and calculate each time the correct phase..
210  if (prevPos == -1||prevPos>mLastPeakArray.GetnPeaks()) // new track...
211  {
212  phase = mRandomPhase[i];
213  peakArray.SetPhase(i,TData(phase));
214 
215  lastPhase[i]=phase;
216  lastFreq[i]=freq;
217  /*SpectralPeak tmpPeak;
218  mLastPeakArray.InitPeak(tmpPeak);
219  tmpPeak.SetPhase(TData(phase));
220  tmpPeak.SetFreq(TData(phase));
221  mLastPeakArray.AddSpectralPeak(tmpPeak);*/
222  }
223  else // track is existing, calculate according phase..
224  {
225  SpectralPeak lastPeak=mLastPeakArray.GetSpectralPeak(prevPos);
226  phase = lastPeak.GetPhase() + TWO_PI*((lastPeak.GetFreq()+freq)*0.5*mFrameTime);
227 
228  //phase = phase - floor(phase/TWO_PI)*TWO_PI;
229  while (phase >= TWO_PI) phase = phase -TWO_PI; // other way..
230  peakArray.SetPhase(i,TData(phase));
231  lastPhase[prevPos]=TData(phase);
232  lastFreq[prevPos]=TData(phase);
233  }
234  }
235  mLastPeakArray.SetIsIndexUpToDate(true);
236 
237 
238 }
239 
240 
242 {
243  int i;
245  int nPeaks = p.GetnPeaks();
246  DataArray& lastPhaseBuffer = mLastPeakArray.GetPhaseBuffer();
247  DataArray& lastFreqBuffer = mLastPeakArray.GetFreqBuffer();
248  DataArray& currentPhaseBuffer = p.GetPhaseBuffer();
249  DataArray& currentFreqBuffer = p.GetFreqBuffer();
250 
251  TData timeDifference = t-mFrameTime;
252  TData halfPI= TData(TWO_PI)*TData(0.5);
253 
254  TData halfPITimeDifference = timeDifference*halfPI;
255  TData twoPITimeDifference = TData(TWO_PI)*timeDifference;
256 
257  for(i=0;i<nPeaks;i++)
258  {
259  TIndex currentIndex=p.GetIndex(i);
260  TIndex lastPos=mLastPeakArray.GetPositionFromIndex(currentIndex);
261  if(lastPos!=-1)
262  {
263  //SpectralPeak tmpPeak=mLastPeakArray.GetSpectralPeak(lastPos);
264  //p.SetPhase(i,tmpPeak.GetPhase()+TData(TWO_PI)*TData(0.5)*(tmpPeak.GetFreq()+p.GetFreq(i))*(t-mFrameTime));
265  currentPhaseBuffer[i] = lastPhaseBuffer[lastPos]+
266  halfPITimeDifference*(lastFreqBuffer[lastPos]+currentFreqBuffer[i]);
267 
268  }
269  else
270  {
271  //p.SetPhase(i,TData(TWO_PI)*p.GetFreq(i)*(t-mFrameTime));
272  currentPhaseBuffer[i] = currentFreqBuffer[i]*twoPITimeDifference;
273  }
274  //p.SetPhase(i,p.GetPhase(i)-floor((TData)(p.GetPhase(i)/TData(TWO_PI)))*TData(TWO_PI));
275  currentPhaseBuffer[i] = currentPhaseBuffer[i]-floor((TData)(currentPhaseBuffer[i]/TData(TWO_PI)))*TData(TWO_PI);
276  }
277  mFrameTime=t;
278  mLastPeakArray=p;
279  mLastPeakArray.SetIsIndexUpToDate(true);
280 }
281 
282 //----------------------------------------------------------------------------//
283 void
285 {
286  for (int i = 0; i<a.Size();i++)
287  {
288  a[i] = rand()/TData(RAND_MAX*TWO_PI);
289  }
290 }
291 //----------------------------------------------------------------------------//
292 void
294 {
295  DataArray& lastPhase=mLastPeakArray.GetPhaseBuffer();
296  DataArray& lastFreq=mLastPeakArray.GetFreqBuffer();
297  DataArray& currentPhase= peakArray.GetPhaseBuffer();
298  DataArray& currentFreq= peakArray.GetFreqBuffer();
299  int nPeaks=peakArray.GetnPeaks();
300 
301  lastPhase.Resize(nPeaks);
302  lastPhase.SetSize(nPeaks);
303  lastFreq.Resize(nPeaks);
304  lastFreq.SetSize(nPeaks);
305 
306  for (int i=0;i<nPeaks;i++)
307  {
308  lastPhase[i] = currentPhase[i];
309  lastFreq[i] = currentFreq[i];
310  }
311  mLastPeakArray.SetIsIndexUpToDate(true);
312 
313 }
314 
315 } // namespace CLAM
316