31 : mInput(
"Input", this ),
32 mOutput(
"Output", this ),
33 mFundFreqValue(
"Fund Freq Value", this )
39 : mInput(
"Input", this ),
40 mOutput(
"Output", this ),
41 mFundFreqValue(
"Fund Freq Value", this )
60 mnMaxSines = mConfig.GetnMaxSines();
62 mThreshold= mConfig.GetThreshold();
64 mHarmonic= mConfig.GetIsHarmonic();
75 mGuideArray.
Resize(mnMaxSines);
77 mGuideArray.
SetSize(mnMaxSines);
78 for(i=0;i<mnMaxSines;i++)
80 mGuideArray[i].isDead=
true;
104 oPeakArray.AddIndexArray();
105 oPeakArray.AddPhaseBuffer();
106 oPeakArray.AddBinWidthBuffer();
107 oPeakArray.AddBinPosBuffer();
111 if(mHarmonic && fn>0)
114 return DoHarmonic(iPeakArray,oPeakArray,fn);
118 if(mLastHarmonic) KillAll();
120 return DoInharmonic(iPeakArray,oPeakArray);
127 for(
int i=0;i<mnMaxSines;i++)
129 if(mGuideArray[i].isDead==
true)
131 mGuideArray[i].isDead=
false;
132 mGuideArray[i].trackId=mNextTrackId;
133 mGuideArray[i].freq=currentPeak.GetFreq();
134 mGuideArray[i].mag=currentPeak.GetMag();
146 void SinTracking::Tracking(
const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray,
TIndex processedPeakPos)
const
148 const DataArray & previousFreqBuffer = mPreviousPeakArray.GetFreqBuffer();
149 const IndexArray & previousIndexBuffer = mPreviousPeakArray.GetIndexArray();
150 TData currentPeakFreq = previousFreqBuffer[processedPeakPos];
152 const DataArray& iFreqBuffer=iPeakArray.GetFreqBuffer();
154 if(!ThereIsCandidate(currentPeakFreq,iPeakArray,oPeakArray))
156 KillTrack(previousIndexBuffer[processedPeakPos]);
161 int candidatePos=GetCandidate(currentPeakFreq,iPeakArray,distance);
162 if(candidatePos==-1)
return;
163 TData candidatePeakFreq = iFreqBuffer[candidatePos];
165 if( candidatePos>=oPeakArray.GetnPeaks()
166 || (!IsBestCandidate(candidatePeakFreq,currentPeakFreq))
167 || (oPeakArray.GetIndex(candidatePos)!=-1) )
169 KillTrack(previousIndexBuffer[processedPeakPos]);
175 const SpectralPeak candidatePeak = iPeakArray.GetSpectralPeak(candidatePos);
176 TIndex trackId = previousIndexBuffer[processedPeakPos];
177 oPeakArray.SetSpectralPeak(candidatePos,candidatePeak,trackId);
183 bool SinTracking::ThereIsCandidate(
TData currentPeakFreq,
184 const SpectralPeakArray& iPeakArray,
185 SpectralPeakArray& oPeakArray)
const
187 TSize nInputPeaks=iPeakArray.GetnPeaks();
188 if(nInputPeaks>mnMaxSines) nInputPeaks=mnMaxSines;
189 DataArray& peakFreqBuffer=iPeakArray.GetFreqBuffer();
190 TData factor=100/currentPeakFreq;
191 IndexArray& outputIndexArray=oPeakArray.GetIndexArray();
192 for (
int i=0;i<nInputPeaks;i++)
194 int dist=
int(
Abs(peakFreqBuffer[i]-currentPeakFreq)*factor);
195 if((dist< mThreshold)&&(outputIndexArray[i]==-1))
return true;
202 void SinTracking::KillTrack(
int trackId)
const
204 for(
int i=0;i<mnMaxSines;i++)
206 if(mGuideArray[i].trackId!=trackId)
continue;
207 mGuideArray[i].isDead=
true;
214 TIndex SinTracking::GetCandidate(
TData currentPeakFreq,
215 const SpectralPeakArray& iPeakArray,
216 TData& distance)
const
220 int nPeaks=iPeakArray.GetnPeaks();
221 DataArray& peakFreqBuffer=iPeakArray.GetFreqBuffer();
222 TData factor=100./currentPeakFreq;
225 SearchArray<TData> mySearch(peakFreqBuffer);
226 TIndex found=mySearch.Find(currentPeakFreq);
227 if (found==-1) found = 0;
228 TIndex originalFound = found;
229 distance =
Abs(peakFreqBuffer[found]-currentPeakFreq);
233 if(originalFound<nPeaks-1)
235 for(newFound=found+1; newFound<nPeaks; newFound++)
237 nextDistance =
Abs(peakFreqBuffer[newFound]-currentPeakFreq);
238 if(nextDistance>distance)
break;
239 distance = nextDistance;
245 for(newFound=found-1; newFound>-1; newFound--)
247 nextDistance =
Abs(peakFreqBuffer[newFound]-currentPeakFreq);
248 if(nextDistance>distance)
break;
249 distance = nextDistance;
251 found = newFound + 1;
261 bool SinTracking::IsBestCandidate(
TData candidateFreq,
TData currentFreq)
const
263 double nextDistance=
Abs(currentFreq-candidateFreq);
265 int nPeaks=mPreviousPeakArray.
GetnPeaks();
266 DataArray& peakFreqBuffer=mPreviousPeakArray.GetFreqBuffer();
267 for(
int i=0;i<nPeaks;i++)
269 if(
Abs(peakFreqBuffer[i]-candidateFreq)<nextDistance)
return false;
279 void SinTracking::Match(
TIndex trackId,
TIndex peakIndex,
280 const SpectralPeak& currentPeak,
281 SpectralPeakArray& oPeakArray)
const
283 CLAM_ASSERT(peakIndex<oPeakArray.GetnPeaks(),
"SinTracking::Match: Not a valid peak Index");
284 oPeakArray.SetSpectralPeak(peakIndex,currentPeak,trackId);
292 void SinTracking::CheckForNewBornTracks(
const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray)
const
294 TIndex nonAssignedPeakIndex=0;
295 bool notFinished=
true;
296 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
299 if(nonAssignedPeakIndex == -1)
309 AddNewTrack(nonAssignedPeakIndex,iPeakArray.GetSpectralPeak(nonAssignedPeakIndex),oPeakArray);
310 nonAssignedPeakIndex++;
311 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
321 TIndex SinTracking::GetFirstNonAssignedPeakPos(
const SpectralPeakArray& oPeakArray,
TIndex beginAt=0)
const
323 const TIndex nPeaks = oPeakArray.GetnPeaks();
324 if (beginAt>=nPeaks)
return -1;
325 if (beginAt<0)
return -1;
327 int i=oPeakArray.GetFirstNonValidIndexPosition(beginAt);
329 if(i==nPeaks)
return -1;
336 void SinTracking::Initialization(
const SpectralPeakArray& iPeakArray, SpectralPeakArray& oPeakArray)
338 TSize nPeaks=oPeakArray.GetnPeaks();
339 for(
int i=0; i<nPeaks; i++)
341 AddNewTrack(i, iPeakArray.GetSpectralPeak(i), oPeakArray);
343 mPreviousPeakArray=oPeakArray;
346 void SinTracking::KillAll()
348 for (
int i=0;i<mnMaxSines;i++)
350 mGuideArray[i].isDead=
true;
355 bool SinTracking::DoInharmonic(
const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray)
357 if(iPeakArray.GetnPeaks()<mnMaxSines)
358 oPeakArray.SetnPeaks(iPeakArray.GetnPeaks());
360 oPeakArray.SetnPeaks(mnMaxSines);
362 oPeakArray.ResetIndices();
363 oPeakArray.InitIndices();
368 Initialization(iPeakArray, oPeakArray);
373 oPeakArray.SetIsIndexUpToDate(
true);
374 for(
int i=0;i<mPreviousPeakArray.
GetnPeaks();i++)
376 Tracking(iPeakArray,oPeakArray,i);
378 CheckForNewBornTracks(iPeakArray,oPeakArray);
379 mPreviousPeakArray=oPeakArray;
389 bool SinTracking::DoHarmonic(
const SpectralPeakArray& in, SpectralPeakArray& out,
TData funFreq)
396 InitHarmonicTracks(out,funFreq);
397 out.SetIsIndexUpToDate(
true);
398 HarmonicTracking(in, out, funFreq);
399 mPreviousPeakArray=out;
404 void SinTracking::HarmonicTracking(
const SpectralPeakArray& in,SpectralPeakArray& out,
TData funFreq)
409 out.SetnPeaks(mnMaxSines);
412 DataArray& oFreqBuffer=out.GetFreqBuffer();
414 DataArray& oMagBuffer=out.GetMagBuffer();
415 DataArray& iPhaseBuffer=in.GetPhaseBuffer();
416 DataArray& oPhaseBuffer=out.GetPhaseBuffer();
421 TSize nPeaks=mnMaxSines;
424 for(n=0; n<mnMaxSines;n++)
426 pos=GetCandidate(oFreqBuffer[i],in,d);
427 if(d<funFreq/2 && pos>-1)
429 if(i==0 || iMagBuffer[pos]!=oMagBuffer[i-1])
431 oMagBuffer[i]=iMagBuffer[pos];
432 oFreqBuffer[i]=oFreqBuffer[n];
433 oPhaseBuffer[i]=iPhaseBuffer[pos];
441 void SinTracking::InitHarmonicTracks(SpectralPeakArray& peaks,
TData funFreq)
443 DataArray& freqBuffer=peaks.GetFreqBuffer();
444 DataArray& magBuffer=peaks.GetMagBuffer();
448 TData currentFreq=funFreq;
450 for(i=0;i<mnMaxSines;i++)
452 freqBuffer[i]=currentFreq;
454 currentFreq+=funFreq;