00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "SinTracking.hxx"
00023 #include "SearchArray.hxx"
00024
00025
00026 namespace CLAM
00027 {
00028
00029
00030 SinTracking::SinTracking()
00031 : mInput("Input", this ),
00032 mOutput("Output", this ),
00033 mFundFreqValue("Fund Freq Value", this )
00034 {
00035 Configure(SinTrackingConfig());
00036 }
00037
00038 SinTracking::SinTracking(const SinTrackingConfig &c )
00039 : mInput("Input", this ),
00040 mOutput("Output", this ),
00041 mFundFreqValue("Fund Freq Value", this )
00042
00043 {
00044 Configure(c);
00045 }
00046
00047 SinTracking::~SinTracking()
00048 {}
00049
00050
00051
00052
00053
00054
00055 bool SinTracking::ConcreteConfigure(const ProcessingConfig& c)
00056 {
00057
00058 CopyAsConcreteConfig(mConfig, c);
00059
00060 mnMaxSines = mConfig.GetnMaxSines();
00061
00062 mThreshold= mConfig.GetThreshold();
00063
00064 mHarmonic= mConfig.GetIsHarmonic();
00065
00066 mnActiveGuides=0;
00067
00068 mNextTrackId=0;
00069
00070 mInitialized=false;
00071 mLastHarmonic=false;
00072
00073 int i;
00074
00075 mGuideArray.Resize(mnMaxSines);
00076
00077 mGuideArray.SetSize(mnMaxSines);
00078 for(i=0;i<mnMaxSines;i++)
00079 {
00080 mGuideArray[i].isDead=true;
00081 }
00082
00083 return true;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 bool SinTracking::Do(void)
00094 {
00095 bool result = Do( mInput.GetData(), mOutput.GetData() );
00096 mInput.Consume();
00097 mOutput.Produce();
00098 return result;
00099 }
00100
00101 bool SinTracking::Do(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray)
00102 {
00103
00104 oPeakArray.AddIndexArray();
00105 oPeakArray.AddPhaseBuffer();
00106 oPeakArray.AddBinWidthBuffer();
00107 oPeakArray.AddBinPosBuffer();
00108 oPeakArray.UpdateData();
00109
00110 TData fn = mFundFreqValue.GetLastValue();
00111 if(mHarmonic && fn>0)
00112 {
00113 mLastHarmonic=true;
00114 return DoHarmonic(iPeakArray,oPeakArray,fn);
00115 }
00116 else
00117 {
00118 if(mLastHarmonic) KillAll();
00119 mLastHarmonic=false;
00120 return DoInharmonic(iPeakArray,oPeakArray);
00121 }
00122 }
00123
00124
00125 void SinTracking::AddNewTrack(int peakPosition, const SpectralPeak& currentPeak,SpectralPeakArray& oPeakArray) const
00126 {
00127 for(int i=0;i<mnMaxSines;i++)
00128 {
00129 if(mGuideArray[i].isDead==true)
00130 {
00131 mGuideArray[i].isDead=false;
00132 mGuideArray[i].trackId=mNextTrackId;
00133 mGuideArray[i].freq=currentPeak.GetFreq();
00134 mGuideArray[i].mag=currentPeak.GetMag();
00135 oPeakArray.SetSpectralPeak(peakPosition,currentPeak, mNextTrackId);
00136 mNextTrackId++;
00137 mnActiveGuides++;
00138 break;
00139 }
00140 }
00141
00142 }
00143
00144
00145
00146 void SinTracking::Tracking(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray,TIndex processedPeakPos) const
00147 {
00148 const DataArray & previousFreqBuffer = mPreviousPeakArray.GetFreqBuffer();
00149 const IndexArray & previousIndexBuffer = mPreviousPeakArray.GetIndexArray();
00150 TData currentPeakFreq = previousFreqBuffer[processedPeakPos];
00151
00152 const DataArray& iFreqBuffer=iPeakArray.GetFreqBuffer();
00153
00154 if(!ThereIsCandidate(currentPeakFreq,iPeakArray,oPeakArray))
00155 {
00156 KillTrack(previousIndexBuffer[processedPeakPos]);
00157 return;
00158 }
00159
00160 TData distance;
00161 int candidatePos=GetCandidate(currentPeakFreq,iPeakArray,distance);
00162 if(candidatePos==-1) return;
00163 TData candidatePeakFreq = iFreqBuffer[candidatePos];
00164
00165 if( candidatePos>=oPeakArray.GetnPeaks()
00166 || (!IsBestCandidate(candidatePeakFreq,currentPeakFreq))
00167 || (oPeakArray.GetIndex(candidatePos)!=-1) )
00168 {
00169 KillTrack(previousIndexBuffer[processedPeakPos]);
00170 return;
00171 }
00172
00173
00174
00175 const SpectralPeak candidatePeak = iPeakArray.GetSpectralPeak(candidatePos);
00176 TIndex trackId = previousIndexBuffer[processedPeakPos];
00177 oPeakArray.SetSpectralPeak(candidatePos,candidatePeak,trackId);
00178 }
00179
00180
00181
00182
00183 bool SinTracking::ThereIsCandidate(TData currentPeakFreq,
00184 const SpectralPeakArray& iPeakArray,
00185 SpectralPeakArray& oPeakArray) const
00186 {
00187 TSize nInputPeaks=iPeakArray.GetnPeaks();
00188 if(nInputPeaks>mnMaxSines) nInputPeaks=mnMaxSines;
00189 DataArray& peakFreqBuffer=iPeakArray.GetFreqBuffer();
00190 TData factor=100/currentPeakFreq;
00191 IndexArray& outputIndexArray=oPeakArray.GetIndexArray();
00192 for (int i=0;i<nInputPeaks;i++)
00193 {
00194 int dist=int(Abs(peakFreqBuffer[i]-currentPeakFreq)*factor);
00195 if((dist< mThreshold)&&(outputIndexArray[i]==-1)) return true;
00196 }
00197 return false;
00198 }
00199
00200
00201
00202 void SinTracking::KillTrack(int trackId) const
00203 {
00204 for(int i=0;i<mnMaxSines;i++)
00205 {
00206 if(mGuideArray[i].trackId!=trackId) continue;
00207 mGuideArray[i].isDead=true;
00208 mnActiveGuides--;
00209 return;
00210 }
00211 }
00212
00213
00214 TIndex SinTracking::GetCandidate(TData currentPeakFreq,
00215 const SpectralPeakArray& iPeakArray,
00216 TData& distance) const
00217 {
00218
00219 distance=-1;
00220 int nPeaks=iPeakArray.GetnPeaks();
00221 DataArray& peakFreqBuffer=iPeakArray.GetFreqBuffer();
00222 TData factor=100./currentPeakFreq;
00223
00224
00225 SearchArray<TData> mySearch(peakFreqBuffer);
00226 TIndex found=mySearch.Find(currentPeakFreq);
00227 if (found==-1) found = 0;
00228 TIndex originalFound = found;
00229 distance = Abs(peakFreqBuffer[found]-currentPeakFreq);
00230
00231 TIndex newFound;
00232 TData nextDistance;
00233 if(originalFound<nPeaks-1)
00234 {
00235 for(newFound=found+1; newFound<nPeaks; newFound++)
00236 {
00237 nextDistance = Abs(peakFreqBuffer[newFound]-currentPeakFreq);
00238 if(nextDistance>distance) break;
00239 distance = nextDistance;
00240 }
00241 found = newFound-1;
00242 }
00243 if(originalFound>0)
00244 {
00245 for(newFound=found-1; newFound>-1; newFound--)
00246 {
00247 nextDistance = Abs(peakFreqBuffer[newFound]-currentPeakFreq);
00248 if(nextDistance>distance) break;
00249 distance = nextDistance;
00250 }
00251 found = newFound + 1;
00252 }
00253 distance *= factor;
00254 return found;
00255 }
00256
00257
00258
00259
00260
00261 bool SinTracking::IsBestCandidate(TData candidateFreq, TData currentFreq) const
00262 {
00263 double nextDistance=Abs(currentFreq-candidateFreq);
00264
00265 int nPeaks=mPreviousPeakArray.GetnPeaks();
00266 DataArray& peakFreqBuffer=mPreviousPeakArray.GetFreqBuffer();
00267 for(int i=0;i<nPeaks;i++)
00268 {
00269 if(Abs(peakFreqBuffer[i]-candidateFreq)<nextDistance) return false;
00270 }
00271 return true;
00272
00273 }
00274
00275
00276
00277
00278
00279 void SinTracking::Match(TIndex trackId, TIndex peakIndex,
00280 const SpectralPeak& currentPeak,
00281 SpectralPeakArray& oPeakArray) const
00282 {
00283 CLAM_ASSERT(peakIndex<oPeakArray.GetnPeaks(),"SinTracking::Match: Not a valid peak Index");
00284 oPeakArray.SetSpectralPeak(peakIndex,currentPeak,trackId);
00285
00286 }
00287
00288
00289
00290
00291
00292 void SinTracking::CheckForNewBornTracks(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray) const
00293 {
00294 TIndex nonAssignedPeakIndex=0;
00295 bool notFinished=true;
00296 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
00297 while(notFinished)
00298 {
00299 if(nonAssignedPeakIndex == -1)
00300 {
00301 notFinished=false;
00302 break;
00303 }
00304 else
00305 {
00306
00307
00308
00309 AddNewTrack(nonAssignedPeakIndex,iPeakArray.GetSpectralPeak(nonAssignedPeakIndex),oPeakArray);
00310 nonAssignedPeakIndex++;
00311 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
00312 }
00313 }
00314
00315 }
00316
00317
00318
00319
00320
00321 TIndex SinTracking::GetFirstNonAssignedPeakPos(const SpectralPeakArray& oPeakArray, TIndex beginAt=0) const
00322 {
00323 const TIndex nPeaks = oPeakArray.GetnPeaks();
00324 if (beginAt>=nPeaks) return -1;
00325 if (beginAt<0) return -1;
00326
00327 int i=oPeakArray.GetFirstNonValidIndexPosition(beginAt);
00328
00329 if(i==nPeaks) return -1;
00330
00331 return i;
00332 }
00333
00334
00335
00336 void SinTracking::Initialization(const SpectralPeakArray& iPeakArray, SpectralPeakArray& oPeakArray)
00337 {
00338 TSize nPeaks=oPeakArray.GetnPeaks();
00339 for(int i=0; i<nPeaks; i++)
00340 {
00341 AddNewTrack(i, iPeakArray.GetSpectralPeak(i), oPeakArray);
00342 }
00343 mPreviousPeakArray=oPeakArray;
00344 }
00345
00346 void SinTracking::KillAll()
00347 {
00348 for (int i=0;i<mnMaxSines;i++)
00349 {
00350 mGuideArray[i].isDead=true;
00351 }
00352 mnActiveGuides=0;
00353 }
00354
00355 bool SinTracking::DoInharmonic(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray)
00356 {
00357 if(iPeakArray.GetnPeaks()<mnMaxSines)
00358 oPeakArray.SetnPeaks(iPeakArray.GetnPeaks());
00359 else
00360 oPeakArray.SetnPeaks(mnMaxSines);
00361
00362 oPeakArray.ResetIndices();
00363 oPeakArray.InitIndices();
00364 oPeakArray.SetScale(EScale(EScale::eLog));
00365
00366 if(!mInitialized)
00367 {
00368 Initialization(iPeakArray, oPeakArray);
00369 mInitialized=true;
00370 return true;
00371 }
00372
00373 oPeakArray.SetIsIndexUpToDate(true);
00374 for(int i=0;i<mPreviousPeakArray.GetnPeaks();i++)
00375 {
00376 Tracking(iPeakArray,oPeakArray,i);
00377 }
00378 CheckForNewBornTracks(iPeakArray,oPeakArray);
00379 mPreviousPeakArray=oPeakArray;
00380
00381
00382
00383
00384 return true;
00385 }
00386
00387
00388
00389 bool SinTracking::DoHarmonic(const SpectralPeakArray& in, SpectralPeakArray& out,TData funFreq)
00390 {
00391 out.SetnPeaks(mnMaxSines);
00392
00393 out.ResetIndices();
00394 out.SetScale(EScale(EScale::eLog));
00395
00396 InitHarmonicTracks(out,funFreq);
00397 out.SetIsIndexUpToDate(true);
00398 HarmonicTracking(in, out, funFreq);
00399 mPreviousPeakArray=out;
00400 return true;
00401
00402 }
00403
00404 void SinTracking::HarmonicTracking(const SpectralPeakArray& in,SpectralPeakArray& out,TData funFreq)
00405 {
00406 TData d;
00407 TIndex pos;
00408
00409 out.SetnPeaks(mnMaxSines);
00410
00411
00412 DataArray& oFreqBuffer=out.GetFreqBuffer();
00413 DataArray& iMagBuffer=in.GetMagBuffer();
00414 DataArray& oMagBuffer=out.GetMagBuffer();
00415 DataArray& iPhaseBuffer=in.GetPhaseBuffer();
00416 DataArray& oPhaseBuffer=out.GetPhaseBuffer();
00417
00418
00419 int i;
00420
00421 TSize nPeaks=mnMaxSines;
00422 i=0;
00423 int n;
00424 for(n=0; n<mnMaxSines;n++)
00425 {
00426 pos=GetCandidate(oFreqBuffer[i],in,d);
00427 if(d<funFreq/2 && pos>-1)
00428 {
00429 if(i==0 || iMagBuffer[pos]!=oMagBuffer[i-1])
00430 {
00431 oMagBuffer[i]=iMagBuffer[pos];
00432 oFreqBuffer[i]=oFreqBuffer[n];
00433 oPhaseBuffer[i]=iPhaseBuffer[pos];
00434 i++;
00435 }
00436 }
00437 }
00438 out.SetnPeaks(i);
00439 }
00440
00441 void SinTracking::InitHarmonicTracks(SpectralPeakArray& peaks, TData funFreq)
00442 {
00443 DataArray& freqBuffer=peaks.GetFreqBuffer();
00444 DataArray& magBuffer=peaks.GetMagBuffer();
00445
00446 int i;
00447
00448 TData currentFreq=funFreq;
00449
00450 for(i=0;i<mnMaxSines;i++)
00451 {
00452 freqBuffer[i]=currentFreq;
00453 magBuffer[i]=-99;
00454 currentFreq+=funFreq;
00455 }
00456 }
00457
00458 }
00459